JavaScript: удалить прослушиватель событий

Я пытаюсь удалить прослушиватель событий внутри определения слушателя:

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

Как я мог это сделать? это = событие ... Спасибо.


person thomas    schedule 09.12.2010    source источник
comment
тривиально, но для будущих ссылок if(click == 50) { должно быть if( click === 50 ) или if( click >= 50 ) - они не изменят вывод, но из соображений здравомыслия эти проверки имеют больше смысла.   -  person rlemon    schedule 15.03.2012
comment
Хороший вопрос ... как мне удалить его, если у меня нет доступа к контенту? Я хочу удалить всплывающие окна для кнопок onclick с помощью greasemonkey для других сайтов, но, если я не могу ссылаться на функцию по имени, я, похоже, не могу найти способ ее удалить.   -  person JasonXA    schedule 26.06.2015


Ответы (7)


Вам нужно использовать именованные функции.

Кроме того, для увеличения переменная 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 ));

РЕДАКТИРОВАТЬ: Я забыл назвать обработчик, возвращаемый в последних двух версиях. Исправлено.

person user113716    schedule 09.12.2010
comment
+1 - Я превратил это в скрипку, и это не сработало. Но это потому, что мне нужно было щелкнуть пятьдесят раз :) Какой я идиот. Упрощенный пример здесь: jsfiddle.net/karim79/aZNqA - person karim79; 09.12.2010
comment
@ karim79: Хотел бы я сказать, что никогда раньше не делал ничего подобного. : o) Спасибо за jsFiddle. - person user113716; 09.12.2010
comment
+1 Третий вариант у меня сработал. Назначение ключевого события полю ввода для очистки проверки. Хороший, спасибо - person Gurnard; 14.11.2011
comment
Голосовать за, третий вариант здесь - важная часть понимания привязки / отмены привязки JS. - person SW4; 19.05.2015
comment
myClick = function(event){...} тоже будет считаться именованной функцией? - person Daniel Möller; 28.07.2015
comment
Интересно, смог бы я сделать: myClick = function...., затем another = myClick и, наконец, removeEventListener('click', another) ?? - person Daniel Möller; 28.07.2015
comment
@Daniel, поскольку myClick(0) возвращает функцию, конечно, вы можете - person alebianco; 20.12.2016

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

Должен это сделать.

person edeverett    schedule 09.12.2010
comment
Это круто! Документ по arguments.callee для заинтересованных сторон: developer.mozilla.org/en/JavaScript / Справка / - person Ender; 09.12.2010
comment
Спасибо, это очень помогло. - person John O; 05.02.2019
comment
К сожалению, это не работает с ECMAScript 5 (2009) или новее, из ссылки MDN: 5-е издание ECMAScript (ES5) запрещает использование arguments.callee() в строгом режиме. Избегайте использования arguments.callee(), задавая функциональным выражениям имя или используя объявление функции, в котором функция должна вызывать сама себя. (хотя он использует callee() вместо callee, он все равно удален, бу!) - person Dai; 30.05.2020

Вы можете использовать именованное выражение функции (в данном случае функция называется 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/.

person Tama    schedule 06.01.2014

Если решение @ Cybernate не работает, попробуйте отключить триггер в его собственной функции, чтобы вы могли ссылаться на него.

clickHandler = function(event){
  if (click++ == 49)
    canvas.removeEventListener('click',clickHandler);
}
canvas.addEventListener('click',clickHandler);
person Brad Christie    schedule 09.12.2010

Если кто-то использует 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 отлично работает :)

person youssman    schedule 08.08.2014

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

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

Это позволит вам удалить обработчик по имени изнутри.

person Ender    schedule 09.12.2010

Попробуй, у меня это сработало.

<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>
person user3870075    schedule 05.11.2016