JavaScript: olay dinleyicisini kaldır


136

Bir dinleyici tanımı içindeki bir olay dinleyicisini kaldırmaya çalışıyorum:

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

Bunu nasıl yapabilirim? this = event ... Teşekkürler.


8
Önemsizdir, ancak gelecekteki referanslar if(click == 50) {için if( click === 50 )ya if( click >= 50 )çıktıyı değiştirmeyeceklerdir, ancak akıl sağlığı nedeniyle bu kontroller daha anlamlı olacaktır.
rlemon

Güzel soru ... İçeriğe erişimim yoksa nasıl kaldırabilirim? Diğer siteler için greasemonkey kullanarak düğmeleri onclick için pop-up'ları kaldırmak istiyorum, ancak işlev adına göre başvuramazsanız, kaldırmak için bir yol bulmak gibi görünmüyor.
JasonXA

Yanıtlar:


122

Adlandırılmış işlevleri kullanmanız gerekir.

Ayrıca, clickdeğişkenin artırılması için işleyicinin dışında olması gerekir.

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);

EDIT:click_counter Değişkeni şöyle kapatabilirsiniz :

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);

Bu şekilde sayacı birkaç öğe arasında artırabilirsiniz.


Bunu istemiyorsanız ve her birinin kendi sayacı olmasını istiyorsanız, bunu yapın:

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 ));

DÜZENLEME: Son iki sürümde iade edilen işleyiciyi adlandırmayı unutmuştum. Sabit.


14
+1 - Bunu bir keman haline getirdim ve işe yaramadı. Ama bunun sebebi elli kez tıklamam gerektiğiydi :) Ne kadar aptalım. Basitleştirilmiş örnek burada: jsfiddle.net/karim79/aZNqA
karim79

4
@ karim79: Keşke daha önce hiç böyle bir şey yapmadığımı söyleyebilseydim. : o) jsFiddle için teşekkürler.
user113716

+1 Üçüncü seçenek benim için çalıştı. Doğrulamayı silmek için giriş alanına önemli bir olay atama. Güzel bir teşekkürler
Gurnard

Olumlu oy, burada üçüncü seçenek JS bağlama / bağlama anlamanın önemli bir parçasıdır
SW4

olur myClick = function(event){...}da adlandırılmış işlev düşünülebilir?
Daniel Möller

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

Yapmalı.


14
Bu havalı! Doc arguments.calleeilgilenen taraflar için: developer.mozilla.org/en/JavaScript/Reference/...
Ender

Teşekkürler, bu çok yardımcı oldu.
John O

2
Maalesef bu, MDN bağlantısından ECMAScript 5 (2009) veya üstü ile çalışmaz: "ECMAScript'in (ES5) 5. sürümü arguments.callee()katı modda kullanımını yasaklar . arguments.callee()İşlev ifadelerine bir ad vermek veya işlev bildirimi kullanmaktan kaçının burada bir işlev kendini çağırmalıdır. " ( callee()bunun yerine kullanıyor olsa da callee, yine de kaldırıldı, boo!)
Dai

59

Aşağıdaki gibi adlandırılmış bir işlev ifadesi kullanabilirsiniz (bu durumda işlevin adı verilir 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 ...
}

Hızlı ve kirli çalışma örneği: http://jsfiddle.net/8qvdmLz5/2/ .

Adlandırılmış işlev ifadeleri hakkında daha fazla bilgi: http://kangax.github.io/nfe/ .


Zeki. NFE'nin faydalı olduğu nadir vakalardan biri. Teşekkürler.
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'in çözümü işe yaramazsa, referans gösterebilmek için tetiği kendi işlevine sokmayı deneyin.

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

4

Birisi jquery kullanıyorsa, bunu şu şekilde yapabilir:

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 );
    }
});

Umarım birine yardımcı olabilir. @ User113716 tarafından verilen yanıtın iyi çalıştığını unutmayın :)


3

Bence işleyici işlevini önceden tanımlamanız gerekebilir, şöyle:

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

Bu, işleyiciyi kendi içinden adıyla kaldırmanıza izin verecektir.


-4

Bunu dene, benim için çalıştı.

<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>
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.