JavaScript: hapus event listener

142

Saya mencoba untuk menghapus event listener di dalam definisi listener:

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

Bagaimana saya bisa melakukan itu? this = event ... Terima kasih.

thomas
sumber
8
sepele tetapi untuk referensi di masa mendatang if(click == 50) {harus if( click === 50 )atau if( click >= 50 )- mereka tidak akan mengubah keluaran, tetapi untuk alasan kewarasan pemeriksaan ini lebih masuk akal.
rlemon
Pertanyaan bagus ... bagaimana cara menghapusnya jika saya tidak memiliki akses ke konten? Saya ingin menghapus popup untuk onclick pada tombol menggunakan greasemonkey untuk situs lain, tetapi kecuali saya dapat mereferensikan fungsi dengan nama, sepertinya saya tidak menemukan cara untuk menghapusnya.
JasonXA

Jawaban:

125

Anda perlu menggunakan fungsi bernama.

Selain itu, clickvariabel harus berada di luar penangan agar bertambah.

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: Anda dapat menutup click_countervariabel seperti ini:

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

Dengan cara ini Anda dapat menaikkan penghitung di beberapa elemen.


Jika Anda tidak menginginkannya, dan ingin masing-masing memiliki penghitungnya sendiri, lakukan ini:

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: Saya lupa menyebutkan nama pawang yang dikembalikan dalam dua versi terakhir. Tetap.

pengguna113716
sumber
15
+1 - Saya membuat ini menjadi biola dan tidak berhasil. Tapi itu karena saya perlu mengklik lima puluh kali :) Betapa bodohnya saya. Contoh sederhana di sini: jsfiddle.net/karim79/aZNqA
karim79
4
@ Karim79: Seandainya saya bisa mengatakan bahwa saya belum pernah melakukan hal seperti itu sebelumnya. : o) Terima kasih untuk jsFiddle tersebut.
pengguna113716
+1 Opsi ketiga berhasil untuk saya. Menetapkan peristiwa kunci ke bidang masukan untuk menghapus validasi. Bagus, terima kasih
Gurnard
Suara positif, opsi ketiga di sini adalah bagian penting dari pemahaman pengikatan / pelepasan JS
SW4
akan myClick = function(event){...}dianggap sebagai fungsi bernama juga?
Daniel Möller
82
   canvas.addEventListener('click', function(event) {
      click++;
      if(click == 50) {
          this.removeEventListener('click',arguments.callee,false);
      }

Harus melakukannya.

edeverett
sumber
15
Ini keren! Dokumen arguments.calleeuntuk pihak yang tertarik: developer.mozilla.org/en/JavaScript/Reference/…
Ender
Terima kasih, ini banyak membantu.
John O
2
Sayangnya ini tidak berfungsi dengan ECMAScript 5 (2009) atau yang lebih baru, dari tautan MDN: "Edisi ke-5 ECMAScript (ES5) melarang penggunaan arguments.callee()dalam mode ketat. Hindari penggunaan arguments.callee()dengan memberi nama ekspresi fungsi atau menggunakan deklarasi fungsi di mana suatu fungsi harus memanggil dirinya sendiri. " (meskipun itu menggunakan callee()bukannya callee, itu masih dihapus, boo!)
Dai
60

Anda bisa menggunakan ekspresi fungsi bernama (dalam hal ini fungsi dinamai abc), seperti ini:

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 ...
}

Contoh kerja cepat dan kotor: http://jsfiddle.net/8qvdmLz5/2/ .

Informasi lebih lanjut tentang ekspresi fungsi bernama: http://kangax.github.io/nfe/ .

Tama
sumber
Pintar. Salah satu kasus langka dimana NFE berguna. Terima kasih.
DanMan
8
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;
};
};
Jendela Vinyl
sumber
7

Jika solusi @ Cybernate tidak berfungsi, coba hentikan pemicu ke fungsinya sendiri sehingga Anda dapat mereferensikannya.

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

Jika seseorang menggunakan jquery, dia bisa melakukannya seperti ini:

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

Semoga bisa membantu seseorang. Perhatikan bahwa jawaban yang diberikan oleh @ user113716 berfungsi dengan baik :)

youssman
sumber
3

Saya pikir Anda mungkin perlu menentukan fungsi penangan sebelumnya, seperti ini:

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

Ini akan memungkinkan Anda untuk menghapus penangan menurut nama dari dalam dirinya sendiri.

Ender
sumber
-4

Coba ini, itu berhasil untuk saya.

<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>
pengguna3870075
sumber