簡體   English   中英

JavaScript:從該偵聽器中刪除事件偵聽器?

[英]JavaScript: remove an event listener from within that listener?

我一直想知道這種方法有多干凈——從那個監聽器中刪除一個事件監聽器。

更新:

在內部,我保留了對象和偵聽器的散列,因此我可以從任何地方刪除事件偵聽器。 我只是關心將其從內部移除。 這樣的行動真的有用嗎?

更新

我問的是關於 addEventListener、removeEventListener 的事情。

您可以傳遞once選項讓偵聽器只執行一次,然后自行刪除。 文檔: https ://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener#Parameters

例子:

  element.addEventListener('eventname', (ev) => {
    console.log("event is captured only once.");
    // do more stuff...
  }, { once: true });

從上面的相同文檔鏈接,現代瀏覽器支持很好,但不適用於 Internet Explorer。

我剛剛看到這個是因為我想知道完全相同的問題!

arguments.callee 是你的朋友......

https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Functions_and_function_scope/arguments/callee

所以你會有

blah.addEventListener('click',function(e){
    e.source.removeEventListener('click', arguments.callee);
    blee bloo bleep
});

這在 Titanium Appcelerator 中有效,所以它也應該在 javascript 中有效(因為它們是同一個東西有點)

注意不要在這個例子中將()添加到 arguments.callee 的末尾,除非你喜歡看到...... bah dum tish! .

事實上,如果你不想使用 arguments.callee,這也可能有效(未經測試):

blah.addEventListener('click', anyThingYouWantHere = function(e){
    e.source.removeEventListener('click', anyThingYouWantHere);
    blee bloo bleep
});

其中“anythingYouWantHere”是您想要的任何變量名稱〜您在添加函數時實際上是在“命名”該函數。

我剛剛制作了一個包裝函數,它生成一個自毀事件監聽器:

let addSelfDestructingEventListener = (element, eventType, callback) => {
    let handler = () => {
        callback();
        element.removeEventListener(eventType, handler);
    };
    element.addEventListener(eventType, handler);
};

到目前為止效果很好:)

@bharal 的回答現在給了我這個解決方案:

//example
addBlurListener(element, field) {
    const listenToBlur = (e) => {
        e.target.removeEventListener(e.type, listenToBlur);
        //your stuff
    };
    element.addEventListener('blur', listenToBlur);
},

您可以嘗試這樣的操作,具體取決於它的調用方式:

some_div.onclick = function () {
    ...
    this.onclick = null;
    // or: some_div.onclick = null;
};

還是您關心的事件監聽器? 因為那些有點復雜。

如果你想讓監聽器只觸發一次,你可以使用這段代碼:

element.addEventListener('eventname', function callback(){}, { once: true }); 

或者使用 wrapper 做同樣的事情:

function addOneTimeEventListener(element, event, callback) {
    const wrapper = e => {
        try {callback(e)} finally {
            element.removeEventListener(event, wrapper);
        };
    }
    element.addEventListener(event, wrapper);
}

// example
addOneTimeEventListener(document.body, 'click', e => {
  console.log('this message only show once.');
});

如果您想決定何時刪除監聽器:

function addEventListener(element, event, callback) {
    const wrapper = e => {
        callback(e, () => element.removeEventListener(event, wrapper));
    }
    element.addEventListener(event, wrapper);
}

// example
let count = 0;
addEventListener(document.body, 'click', (e, closeListener) => {
  console.log(`click:${++count}`);
  if(count == 3) closeListener();
});

如果您使用 jQuery,您可能會公開一些方便的方法來與事件處理程序進行交互——請參閱 bind()/unbind()、delegate()/undelegate()、one() 和類似的方法

我對其他框架沒有太多經驗,但我想它們會提供類似的功能。 如果您根本不使用框架,@sdleihssirhc 有一個可以接受的答案。

編輯:啊,也許你正在尋找更像addEventListener()removeEventListener()的東西。 同樣,框架將為您的交互提供一些便利,並在某些情況下為您省去重新發明輪子的麻煩。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM