जावास्क्रिप्ट: ईवेंट श्रोता को हटा दें


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 )- वे उत्पादन में बदलाव नहीं करेंगे, लेकिन पवित्रता कारणों से ये चेक अधिक समझ में आते हैं।
rlemon

अच्छा सवाल ... अगर सामग्री तक मेरी पहुँच नहीं है तो मैं इसे कैसे निकालूँ? मैं अन्य साइटों के लिए ग्रीसीकेम का उपयोग करके बटन पर ऑनक्लिप के लिए पॉपअप निकालना चाहता हूं, लेकिन जब तक मैं नाम से फ़ंक्शन को संदर्भित नहीं कर सकता, मुझे इसे हटाने का कोई तरीका नहीं लगता है।
जेसनएक्सए

जवाबों:


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: काश मैं कह सकता कि मैंने पहले कभी ऐसा कुछ नहीं किया। : ओ) jsFiddle के लिए धन्यवाद।
user113716

+1 तीसरा विकल्प मेरे लिए काम करता है। सत्यापन को साफ़ करने के लिए एक महत्वपूर्ण घटना को इनपुट फ़ील्ड में असाइन करना। एक अच्छा धन्यवाद
गर्नार्ड

अपवोट, यहां तीसरा विकल्प जेएस बाइंडिंग / अनबाइंडिंग को समझने का महत्वपूर्ण हिस्सा है
एसडब्ल्यू 4

होगा 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/en/JavaScript/Reference/...
Ender

धन्यवाद, इससे बहुत मदद मिली।
जॉन ओ

2
दुर्भाग्य से यह एमडीएम 5 लिंक (2009) या बाद में एमडीएन लिंक से काम नहीं करता है: "ईसीएमएस्क्रिप्ट (ईएस 5) के 5 वें संस्करण 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

यदि @ साइबरनेट का समाधान काम नहीं करता है, तो ट्रिगर को तोड़ने का प्रयास करें यह स्वयं का कार्य है ताकि आप इसे संदर्भित कर सकें।

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 Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.