日韩成人免费在线_国产成人一二_精品国产免费人成电影在线观..._日本一区二区三区久久久久久久久不

當前位置:首頁 > 科技  > 軟件

Vue 點擊彈窗外部,實現彈窗關閉?你有實現的思路嗎?

來源: 責編: 時間:2024-06-25 17:13:21 171觀看
導讀背景記得以前面試官問過我一個問題:我現在有一個彈窗,怎樣才能實現點擊彈窗以外的區域,實現關閉彈窗呢?當時確實比較菜,沒想出應該怎么做才行,因為當時我的腦子里只有 click事件,我在想點擊事件不是只能綁定在本元素身上嗎?怎

背景

記得以前面試官問過我一個問題:我現在有一個彈窗,怎樣才能實現點擊彈窗以外的區域,實現關閉彈窗呢?0ZL28資訊網——每日最新資訊28at.com

當時確實比較菜,沒想出應該怎么做才行,因為當時我的腦子里只有 click事件,我在想點擊事件不是只能綁定在本元素身上嗎?怎么才能點擊其他地方來影響本元素呢?0ZL28資訊網——每日最新資訊28at.com

0ZL28資訊網——每日最新資訊28at.com

實現思路

過了一兩年后,回頭發現,其實實現并不困難,很多人其實也都會,換一種說法,面試官想問的是:在 Vue 中,有一個元素X,怎么做到點擊元素X以外的東西,觸發綁定在元素X上的事件。0ZL28資訊網——每日最新資訊28at.com

我把實現思路分為幾步:0ZL28資訊網——每日最新資訊28at.com

  • 定義一個 Map,來收集彈窗元素
  • 監聽 document 的鼠標按下、松開事件
  • document 鼠標按下時記錄觸發的元素A
  • document 鼠標松開時遍歷 Map 中所有彈窗元素,讓這些彈窗元素跟元素A一一比較,不等于則說明是點了彈窗元素外部,等于則說明點擊了彈窗元素內部
  • 點擊了外部則觸發綁定事件,點擊了內部則不觸發

ClickOutside

其實上面的思路,就是 v-clickoutside的實現思路,這個自定義指令,是 Vue 中用的非常廣泛的指令~具體用法是這樣的:0ZL28資訊網——每日最新資訊28at.com

cs () {  console.log('點擊外部')}<div v-clickoutside="cs"></div><button>點我</button><button>哈哈哈</button>

當你點擊了 div 元素,也就是本元素,并不會觸發事件 cs,而當你點擊它以外的元素,則會觸發 cs 事件。0ZL28資訊網——每日最新資訊28at.com

代碼實現

1.TypeScript類型準備

// vue自帶的一些類型import type { ComponentPublicInstance, DirectiveBinding, ObjectDirective } from 'vue';// 下面會用到,是記錄綁定事件的函數type DocumentHandler = <T extends MouseEvent>(mouseup: T, mousedown: T) => void;// Map 的類型// key 是元素本地// value 是綁定的事件type FlushList = Map<  HTMLElement,  DocumentHandler>;

2.綁定事件函數

首先封裝一個綁定事件的函數,大家在平時封裝函數的時候一定要注意判空,兜底~0ZL28資訊網——每日最新資訊28at.com

export function on(  element: Element | HTMLElement | Document | Window,  event: string,  handler: EventListenerOrEventListenerObject,): void {  if (element && event && handler) {    element.addEventListener(event, handler, false);  }}

3.判斷點擊元素是否是本元素

想一想我們的目的是啥,有一元素A,我需要點擊元素A以外的地方才觸發綁定的事件,點擊元素A或者元素A以內的區域則不觸發0ZL28資訊網——每日最新資訊28at.com

所以這個函數主要做幾件事:0ZL28資訊網——每日最新資訊28at.com

  • 判斷點擊的元素是否是本元素(不觸發)
  • 判斷點擊的元素是否在本元素內(不觸發)
  • 兜底,判斷元素是否存在(觸發)
function createDocumentHandler(el: HTMLElement, binding: DirectiveBinding): DocumentHandler {  return function (mouseup, mousedown) {    const mouseUpTarget = mouseup.target as Node;    const mouseDownTarget = mousedown.target as Node;    const isBound = !binding || !binding.instance;    const isTargetExists = !mouseUpTarget || !mouseDownTarget;    const isContainedByEl = el.contains(mouseUpTarget) || el.contains(mouseDownTarget);    const isSelf = el === mouseUpTarget;    if (      isBound ||      isTargetExists ||      isContainedByEl ||      isSelf    ) {      return;    }    binding.value();  };}

4.自定義指令

自定義指令的幾個生命周期里,需要做這些事:0ZL28資訊網——每日最新資訊28at.com

  • 綁定時,記錄綁定元素與綁定事件到 nodeList 中
  • 更新時,記錄綁定元素與綁定事件到 nodeList 中
  • 銷毀時,將此元素從 nodeList 中抹除
// 記錄綁定元素的 Mapconst nodeList: FlushList = new Map();const ClickOutside: ObjectDirective = {  beforeMount(el, binding) {    nodeList.set(el,       createDocumentHandler(el, binding));  },  updated(el, binding) {    nodeList.set(el,       createDocumentHandler(el, binding));  },  unmounted(el) {    nodeList.delete(el);  },};export default ClickOutside;

5.監聽 document 鼠標按下、松開

萬事俱備只欠東風,現在只需要監聽 document 的鼠標按下、松開事件 即可,大概分為幾步:;0ZL28資訊網——每日最新資訊28at.com

  • 鼠標按下時,記錄這個觸發的元素
  • 鼠標松開時,遍歷 nodeList 中的元素,跟這個觸發元素做對比
  • 符合條件則執行綁定事件,不符合則不執行
let startClick: MouseEvent;on(document, 'mousedown', (e: MouseEvent) => (startClick = e));on(document, 'mouseup', (e: MouseEvent) => {  for (const { documentHandler } of nodeList.values()) {    documentHandler(e, startClick);  }});

這就實現了點擊外部觸發內部事件的效果了!0ZL28資訊網——每日最新資訊28at.com

本文鏈接:http://www.www897cc.com/showinfo-26-96418-0.htmlVue 點擊彈窗外部,實現彈窗關閉?你有實現的思路嗎?

聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。郵件:2376512515@qq.com

上一篇: 寧德時代曾毓群回應“奮斗一百天”:號召練好基本功,沒有強迫大家

下一篇: Java 流式編程的七個必學技巧

標簽:
  • 熱門焦點
  • 0糖0卡0脂 旭日森林仙草烏龍茶優惠:15瓶到手29元

    旭日森林無糖仙草烏龍茶510ml*15瓶平時要賣為79.9元,今日下單領取50元優惠券,到手價為29.9元。產品規格:0糖0卡0脂,添加草本仙草汁,清涼爽口,富含茶多酚,保留
  • 一篇聊聊Go錯誤封裝機制

    %w 是用于錯誤包裝(Error Wrapping)的格式化動詞。它是用于 fmt.Errorf 和 fmt.Sprintf 函數中的一個特殊格式化動詞,用于將一個錯誤(或其他可打印的值)包裝在一個新的錯誤中。使
  • .NET 程序的 GDI 句柄泄露的再反思

    一、背景1. 講故事上個月我寫過一篇 如何洞察 C# 程序的 GDI 句柄泄露 文章,當時用的是 GDIView + WinDbg 把問題搞定,前者用來定位泄露資源,后者用來定位泄露代碼,后面有朋友反
  • 虛擬鍵盤 API 的妙用

    你是否在遇到過這樣的問題:移動設備上有一個固定元素,當激活虛擬鍵盤時,該元素被隱藏在了鍵盤下方?多年來,這一直是 Web 上的默認行為,在本文中,我們將探討這個問題、為什么會發生
  • 從零到英雄:高并發與性能優化的神奇之旅

    作者 | 波哥審校 | 重樓作為公司的架構師或者程序員,你是否曾經為公司的系統在面對高并發和性能瓶頸時感到手足無措或者焦頭爛額呢?筆者在出道那會為此是吃盡了苦頭的,不過也得
  • 中國家電海外掘金正當時|出海專題

    作者|吳南南編輯|胡展嘉運營|陳佳慧出品|零態LT(ID:LingTai_LT)2023年,出海市場戰況空前,中國創業者在海外紛紛摩拳擦掌,以期能夠把中國的商業模式、創業理念、戰略打法輸出海外,他們依
  • iQOO 11S或7月上市:搭載“雞血版”驍龍8Gen2 史上最強5G Soc

    去年底,iQOO推出了“電競旗艦”iQOO 11系列,作為一款性能強機,iQOO 11不僅全球首發2K 144Hz E6全感屏,搭載了第二代驍龍8平臺及144Hz電競屏,同時在快充
  • 引領旗艦級影像能力向中端機普及 OPPO K11 系列發布 1799 元起

    7月25日,OPPO正式發布K系列新品—— OPPO K11 。此次 K11 在中端手機市場長期被忽視的影像板塊發力,突破性地搭載索尼 IMX890 旗艦大底主攝,支持 OIS
  • 聯想小新Pad Pro 12.6將要推出,搭載高通驍龍 870 處理器

    聯想小新Pad Pro 12.6將于秋季新品會上推出,官方按照慣例直接在發布會前給出了機型的所有參數。聯想小新 Pad Pro 12.6 將搭載高通驍龍 870 處理器,重量為 5
Top 主站蜘蛛池模板: 准格尔旗| 巴林左旗| 郎溪县| 嫩江县| 工布江达县| 江永县| 永德县| 思南县| 大丰市| 丰原市| 靖安县| 特克斯县| 莱阳市| 柞水县| 嵊泗县| 霞浦县| 海林市| 德州市| 株洲县| 南投县| 深水埗区| 林口县| 读书| 城步| 日土县| 资中县| 陆丰市| 颍上县| 缙云县| 和林格尔县| 湛江市| 徐州市| 会宁县| 郯城县| 通道| 门头沟区| 周至县| 高陵县| 肃宁县| 柘荣县| 西畴县|