## 前言 雖然平常想完成 click outside 的功能時,我會直接使用 [click-outside-vue3](https://www.npmjs.com/package/click-outside-vue3) 這個套件,這裡記錄該怎麼自己寫。 ### 為什麼需要自己寫? 因為像是 `addEventListener` 無法使用 vue 自定義事件,只能使用原生的 DOM 事件,所以就不能使用 `click-outside-vue3` 套件。 ## 邏輯 在 document 上加一個 `mousedown` 或 `mouseup` 事件監聽器,當點擊頁面時,去判斷點擊的元素是否在你想要做 click outside 的元素內,不在的話則做對應的行為。 > `mousedown`: 當滑鼠按下時觸發 > `mouseup`: 當滑鼠的按鍵鬆開時觸發 ## 寫法 ```javascript const YOUR_ELEMENT = document.querySelector(".YOUR_ELEMENT"); document.addEventListener("mousedown", (event) => { if (!YOUR_ELEMENT.contains(event.target)) { // click outside handler } }); ``` ## 養成好習慣:移除監聽事件 在 `onMounted` 中添加監聽器,在 `onBeforeUnmount` 中移除監聽器。 ```javascript let removeYourListener = null; onMounted(()=>{ ... const YOUR_ELEMENT = document.querySelector(".YOUR_ELEMENT"); removeYourListener = (event) => { if (!YOUR_ELEMENT.contains(event.target)) { // click outside handler } }; document.addEventListener("mousedown", removeYourListener); }) }); onBeforeUnmount(() => { if (removeYourListener) { document.removeEventListener("mousedown", removeYourListener); } }); ``` ## 可以自行增加不想觸發的位置 只要添加判斷不想觸發的位置是否包含 `event.target` 即可。 ```javascript if (!YOUR_ELEMENT.contains(event.target) && !OTHER_ELEMENT.contains(event.target)) { // click outside handler } ```