AVt天堂网 手机版,亚洲va久久久噜噜噜久久4399,天天综合亚洲色在线精品,亚洲一级Av无码毛片久久精品

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

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

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

背景

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

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

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

實現思路

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

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

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

ClickOutside

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

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

當你點擊了 div 元素,也就是本元素,并不會觸發事件 cs,而當你點擊它以外的元素,則會觸發 cs 事件。HsG28資訊網——每日最新資訊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.綁定事件函數

首先封裝一個綁定事件的函數,大家在平時封裝函數的時候一定要注意判空,兜底~HsG28資訊網——每日最新資訊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以內的區域則不觸發HsG28資訊網——每日最新資訊28at.com

所以這個函數主要做幾件事:HsG28資訊網——每日最新資訊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.自定義指令

自定義指令的幾個生命周期里,需要做這些事:HsG28資訊網——每日最新資訊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 的鼠標按下、松開事件 即可,大概分為幾步:;HsG28資訊網——每日最新資訊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);  }});

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

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

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

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

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

標簽:
  • 熱門焦點
Top