我有一個表示要應用于全屏選單元素的操作的類this.menu。
看起來像這樣(省略了大部分代碼)。關鍵點是clickOutsideHandler偵聽器,它將檢查是否this.menu包含事件目標節點:如果不包含,則應關閉選單:
class Menu {
clickOutsideHandler = e => {
if (!this.menu.contains(e.target)) {
this.close();
}
};
open() {
// Apply style changes
// Add an event listeners
document.addEventListener('click', this.clickOutsideHandler);
}
close() {
// Revert style changes...
// Remove event listeners
document.removeEventListener('click', this.clickOutsideHandler);
}
}
這里的問題this.clickOutsideHandler是添加“太快”,甚至觸發點擊獲取被偵聽器攔截,在實際顯示選單之前:
document.querySelectorAll('[data-menu-trigger]').forEach(trigger => {
trigger.addEventListener('click', e => {
e.preventDefault();
// Call open() on the menu instance
menu.open();
});
});
添加事件偵聽器之前的小超時將解決問題。我還有什么其他選擇?
uj5u.com熱心網友回復:
它觸發的原因是因為事件在樹上冒泡,直到它到達現在具有處理程式的檔案。
你可以stopPropagation()參加活動。這樣它就不會冒泡。
您還可以檢查事件目標是否是[data-menu-trigger]并且不關閉選單。
編輯:
在不觸及觸發器定義部分的情況下,除了使用超時解決它之外,您無能為力……或者有嗎?超時只會將處理程式的應用程式延遲到事件得到完全處理之后。我們可以通過檢查打開和關閉請求之間是否存在延遲來改變事情......
通過添加一個存盤選單打開時的當前時間的屬性,并在我們嘗試關閉選單時檢查該時間,您可以確保僅在兩個事件之間經過 10 毫秒或其他時間時才關閉。
可能不是更干凈或任何東西,但讓我們在不添加超時和觸摸您不想更改的代碼的情況下解決它。
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/504814.html
標籤:javascript dom
上一篇:用JavaScript撰寫JSX
