JavaScript: видаліть слухача подій


136

Я намагаюся видалити слухача подій усередині визначення слухача:

canvas.addEventListener('click', function(event) {
    click++;
    if(click == 50) {
        // remove this event listener here!
    }
// More code here ...

Як я міг це зробити? це = подія ... Дякую.


8
тривіальними, але для майбутніх посилань if(click == 50) {повинні бути if( click === 50 )або if( click >= 50 )- вони не змінять вихід, але з міркувань розумності ці перевірки мають більше сенсу.
роман

Добре запитання ... як її видалити, якщо я не маю доступу до вмісту? Я хочу видалити спливаючі вікна для натискання кнопок на кнопках за допомогою жировика для інших сайтів, але якщо я не можу посилатись на функцію по імені, я, здається, не знаходжу способу її видалити.
JasonXA

Відповіді:


121

Потрібно використовувати названі функції.

Крім того, clickзмінна повинна збільшуватися поза обробником для збільшення.

var click_count = 0;

function myClick(event) {
    click_count++;
    if(click_count == 50) {
       // to remove
       canvas.removeEventListener('click', myClick);
    }
}

// to add
canvas.addEventListener('click', myClick);

РЕДАКТУВАННЯ. Ви можете закрити цю click_counterзмінну:

var myClick = (function( click_count ) {
    var handler = function(event) {
        click_count++;
        if(click_count == 50) {
           // to remove
           canvas.removeEventListener('click', handler);
        }
    };
    return handler;
})( 0 );

// to add
canvas.addEventListener('click', myClick);

Таким чином ви можете збільшити лічильник на декілька елементів.


Якщо ви цього не хочете і хочете, щоб у кожного був свій лічильник, то зробіть це:

var myClick = function( click_count ) {
    var handler = function(event) {
        click_count++;
        if(click_count == 50) {
           // to remove
           canvas.removeEventListener('click', handler);
        }
    };
    return handler;
};

// to add
canvas.addEventListener('click', myClick( 0 ));

EDIT: Я забув назвати обробника, який повернувся в останніх двох версіях. Виправлено.


14
+1 - Я перетворив це на загадку, і це не спрацювало. Але це було тому, що мені потрібно було натиснути п’ятдесят разів :) Який ідіот я. Спрощений приклад тут: jsfiddle.net/karim79/aZNqA
karim79

4
@ karim79: Я б хотів сказати, що ніколи раніше подібного не робив. : o) Дякую за jsFiddle.
user113716

+1 Третій варіант працював для мене. Призначення ключової події полі введення для очищення перевірки. Приємна подяка
Гурнард

Оновлення, третій варіант тут є важливою частиною розуміння прив'язки / розв’язування JS
SW4,

буде myClick = function(event){...}розглядатися як функція з ім'ям теж?
Даніель Мьоллер

80
   canvas.addEventListener('click', function(event) {
      click++;
      if(click == 50) {
          this.removeEventListener('click',arguments.callee,false);
      }

Повинен це робити.


14
Це круто! Документ щодо arguments.calleeзацікавлених сторін: developer.mozilla.org/uk/JavaScript/Reference/…
Ендер

Дякую, це допомогло багато.
Джон О

2
На жаль, це не працює з ECMAScript 5 (2009) або пізнішої версії, за посиланням MDN: "П'яте видання ECMAScript (ES5) забороняє використовувати arguments.callee()в суворому режимі. Уникайте використання arguments.callee(), не даючи вирази функцій імені або використовувати декларацію функції де функція повинна викликати себе. " (хоча він використовується callee()замість цього callee, він все-таки видаляється, бу!)
Дай

59

Ви можете використовувати названий вираз функції (у цьому випадку функція названа abc), наприклад:

let click = 0;
canvas.addEventListener('click', function abc(event) {
    click++;
    if (click >= 50) {
        // remove event listener function `abc`
        canvas.removeEventListener('click', abc);
    }
    // More code here ...
}

Швидкий і брудний приклад роботи: http://jsfiddle.net/8qvdmLz5/2/ .

Детальніше про названі вирази функцій: http://kangax.github.io/nfe/ .


Розумний. Один з тих рідкісних випадків, коли НФЕ корисні. Дякую.
DanMan

7
element.querySelector('.addDoor').onEvent('click', function (e) { });
element.querySelector('.addDoor').removeListeners();


HTMLElement.prototype.onEvent = function (eventType, callBack, useCapture) {
this.addEventListener(eventType, callBack, useCapture);
if (!this.myListeners) {
    this.myListeners = [];
};
this.myListeners.push({ eType: eventType, callBack: callBack });
return this;
};


HTMLElement.prototype.removeListeners = function () {
if (this.myListeners) {
    for (var i = 0; i < this.myListeners.length; i++) {
        this.removeEventListener(this.myListeners[i].eType, this.myListeners[i].callBack);
    };
   delete this.myListeners;
};
};

6

Якщо рішення @ Cybernate не працює, спробуйте відключити тригер у власній функції, щоб ви могли посилатися на нього.

clickHandler = function(event){
  if (click++ == 49)
    canvas.removeEventListener('click',clickHandler);
}
canvas.addEventListener('click',clickHandler);

4

Якщо хтось використовує jquery, він може це зробити так:

var click_count = 0;
$( "canvas" ).bind( "click", function( event ) {
    //do whatever you want
    click_count++;
    if ( click_count == 50 ) {
        //remove the event
        $( this ).unbind( event );
    }
});

Сподіваюсь, що це може комусь допомогти. Зауважте, що відповідь, яку дав @ user113716, працює добре :)


2

Я думаю, вам може знадобитися визначити функцію обробника заздалегідь, наприклад:

var myHandler = function(event) {
    click++; 
    if(click == 50) { 
        this.removeEventListener('click', myHandler);
    } 
}
canvas.addEventListener('click', myHandler);

Це дозволить вам видалити обробник на ім'я з себе.


-4

Спробуйте це, у мене це спрацювало.

<button id="btn">Click</button>
<script>
 console.log(btn)
 let f;
 btn.addEventListener('click', f=function(event) {
 console.log('Click')
 console.log(f)
 this.removeEventListener('click',f)
 console.log('Event removed')
})  
</script>
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.