জাভাস্ক্রিপ্টে বেনামে ফাংশনগুলিতে মুছে ফেলুনEventListener


106

আমার একটি অবজেক্ট রয়েছে যার এতে পদ্ধতি রয়েছে। এই পদ্ধতিগুলি বেনামে ফাংশনটির ভিতরে অবজেক্টে রাখা হয়। দেখে মনে হচ্ছে:

var t = {};
window.document.addEventListener("keydown", function(e) {
    t.scroll = function(x, y) {
        window.scrollBy(x, y);
    };
    t.scrollTo = function(x, y) {
        window.scrollTo(x, y);
    };
});  

(আরও অনেক কোড রয়েছে তবে সমস্যাটি দেখানোর জন্য এটি যথেষ্ট)

এখন আমি কিছু পরিস্থিতিতে ইভেন্ট শ্রোতাদের থামাতে চাই। অতএব আমি একটি অপসারণকারী তালিকা করার চেষ্টা করছি তবে কীভাবে এটি করব তা আমি বুঝতে পারি না। আমি অন্যান্য প্রশ্নের মধ্যে পড়েছি যে বেনামে ফাংশনগুলিতে রিমুভেন্ট লাস্টারকে কল করা সম্ভব নয়, তবে এই পরিস্থিতিতেও কি এই অবস্থাটি রয়েছে?

আমার বেনামে ফাংশনের ভিতরে একটি পদ্ধতি তৈরি হয়েছে এবং তাই আমি ভেবেছিলাম এটি সম্ভব হয়েছিল। এটা এমন দেখতে:

t.disable = function() {
    window.document.removeEventListener("keydown", this, false);
}

আমি কেন এটি করতে পারি না?

এটি করার জন্য অন্য কোনও (ভাল) উপায় আছে?

বোনাস তথ্য; এটি কেবল সাফারিতে কাজ করতে পারে, তাই আই আই সমর্থনটি অনুপস্থিত।


কেন এই ফাংশনটি সংরক্ষণ করবেন না? ইভেন্ট হ্যান্ডলারটি কোনও বেনামি কাজ হতে পারে না।
কিরিলয়েড

4
আমি বুঝতে পেরেছি যে এটি একটু দেরিতে হয়েছে তবে আপনি কোনও উপাদান সম্পর্কে ডেটা সঞ্চয় করার জন্য নোড.সেটউসারডেটা / নোড.জেট ব্যবহারকারী ব্যবহারকারী ডেটাও ব্যবহার করতে পারেন । উদাহরণস্বরূপ, যখন আপনাকে আনোন শ্রোতা সেট করতে হবে (এবং এটি মুছে ফেলতে সক্ষম হবেন), প্রথমে ইউনডাটাটা আনোন ফাংশনে সেট করুন (Elem.setUserData('eventListener', function(e){console.log('Event fired.');}, null);এবং তারপরে Elem.addEventListener ('ইভেন্ট', Elem.getUserData ('ইভেন্টলিস্টার'), মিথ্যা) করুন; ... এবং অপসারণওয়ের জন্য একই। আশা করি আপনি এই ঠিকঠাক দেখতে পাবেন।
চেজ

সম্পাদনা: পূর্ববর্তী মতামত অনুসারে, আমি অনুমান করি যে কেবল ফায়ারফক্সে কাজ করে ... আমি সবেমাত্র আই 8 (আইআই 9 অজানা), সাফারি 5.1.2, ক্রোম (?), অপেরা 11..কোনও পাশ নেই
চেইস

উত্তর:


79

আমি বিশ্বাস করি এটি একটি বেনামি ফাংশনের মূল বিষয়, এটির নাম বা রেফারেন্সের উপায় নেই।

আমি যদি আপনি ছিলাম আমি কেবল একটি নামকৃত ফাংশন তৈরি করব, বা এটি একটি ভেরিয়েবলে রেখে দেব যাতে আপনার কাছে এটির একটি উল্লেখ থাকে।

var t = {};
var handler = function(e) {
    t.scroll = function(x, y) {
        window.scrollBy(x, y);
    };
    t.scrollTo = function(x, y) {
        window.scrollTo(x, y);
    };
};
window.document.addEventListener("keydown", handler);

এরপরে আপনি এটিকে সরাতে পারেন

window.document.removeEventListener("keydown", handler);   

4
ধন্যবাদ তোমার উত্তরের জন্য. আমি গিয়েছিলাম: var হ্যান্ডলার; window.docament.addEventListener ("কীডাউন", হ্যান্ডলার = ফাংশন (ঙ) {তবে আমি যা বুঝতে পারি না তা কেন "এটি" ইভেন্ট শ্রোতাকে রেফারেন্স করে না an ইভেন্ট শ্রোতা কি বস্তু হওয়া উচিত নয়?
বিটকিড

4
thisশব্দ বিভ্রান্তিকর হতে পারে। এটি পড়ার জন্য একটি ভাল জায়গাটি হল quirksmode.org/js/this.html
অ্যাডাম হিথ

আপনাকে অনেক ধন্যবাদ. এটি সবচেয়ে সহায়ক ছিল।
বিটকিড

একটি ওয়েবসাইটে সত্যই অবিরাম বিজ্ঞাপনটি ব্লক করার জন্য আমি এটি করার চেষ্টা করছি। আমি জানি যে এটি বেনামে ফাংশনগুলির বিন্দু, তবে এর অর্থ এই নয় যে আমি কীভাবে এটি করব তা জানতে চাই না।
Wyatt8740

@ বিটকিড: হ্যান্ডলার ফাংশনের অভ্যন্তরে (ধরে নেওয়া এটি কোনও তীর ফাংশন নয়) thisশ্রোতার সাথে যুক্ত হওয়া উপাদানটিকে বোঝায়, ইভেন্টটি নিজেই নয় (যা প্যারামিটার হবে e)। অতএব this === e.currentTarget। পঠিত developer.mozilla.org/en-US/docs/Web/API/EventTarget/...
chharvey

100

আপনি যদি আসল ফাংশনের ভিতরে থাকেন তবে আপনি ফাংশনের রেফারেন্স হিসাবে আর্গুমেন্টস.কলে ব্যবহার করতে পারেন। যেমন হিসাবে:

button.addEventListener('click', function() {
      ///this will execute only once
      alert('only once!');
      this.removeEventListener('click', arguments.callee);
});

সম্পাদনা: আপনি কঠোর মোডে ( "use strict";) কাজ করে থাকলে এটি কাজ করবে না


4
এটি দুর্দান্ত কারণ এটি বেনাম ফাংশনগুলির সুবিধাগুলি সংরক্ষণ করে (নেমস্পেস দূষণকারী নয়)।
bompf

4
উইনজেএস অ্যাপে এটি চেষ্টা করে, পরবর্তী ত্রুটিটি পেয়েছে: "আর্গুমেন্ট অবজেক্টের 'কলি' সম্পত্তি অ্যাক্সেসের কঠোর মোডে অনুমোদিত নয়"
ভ্যালেন্টিন ক্যান্টর

4
@ ভ্যালেন্টিনক্যান্টর: কারণ কোডটিতে কিছু আছে "ব্যবহার কঠোর"; বিবৃতি, এবং আপনি কড়া মোডে কলি ব্যবহার করতে পারবেন না।
ওএমএ

20
ইনলাইন ফাংশন একটি নাম দিন এবং আপনার arguments.callee অবলম্বন না এটা উল্লেখ করতে পারেন:button.addEventListener('click', function handler() { this.removeEventListener('click', handler); });
হ্যারি ভালবাসা

4
মজিলায় বর্ণিত হিসাবে: "সতর্কতা: ECMAScript (ES5) এর 5 তম সংস্করণটি কঠোর মোডে আর্গুমেন্টস callee () ব্যবহার নিষিদ্ধ করেছে function নিজেই ফোন করতে হবে। "
ডুড

53

কট্টর মোডে কাজ করে অটো ন্যাসকারেলার সমাধানের একটি সংস্করণ :

button.addEventListener('click', function handler() {
      ///this will execute only once
      alert('only once!');
      this.removeEventListener('click', handler);
});

4
সুন্দর সমাধান!
এরিক নরক্রস

4
এটি সঠিক উপায় নাও হতে পারে তবে এটি সবচেয়ে সহজ জিনিস।
ভিগনেশ

7
window.document.removeEventListener("keydown", getEventListeners(window.document.keydown[0].listener));  

বেশ কয়েকটি বেনাম ফাংশন হতে পারে, কীডাউন 1

সতর্কতা: শুধুমাত্র কাজ করে Chrome Dev Tools& কোডে ব্যবহার করা যাবে না : লিংক


4
ধন্যবাদ, আপনি কমপক্ষে ক্রোমে একটি ধাঁধা সমাধান করেছেন, যার জন্য অনেক জোকাররা যা বলেছিলেন তা অসম্ভব। মানুষ, তুমি ... ব্যাটম্যান!
জেসনএক্সএ

21
getEventListenersক্রোম দেব-সরঞ্জামগুলির অংশ বলে মনে হচ্ছে, তাই ডিবাগিং ব্যতীত অন্য কোনও কিছুর জন্য সত্যই ব্যবহারযোগ্য নয়।
ডিবিএস

4
এটি চেষ্টা করেই নিশ্চিত করেছেন যে এটি কেবলমাত্র দেবতুলগুলিতে উপলব্ধ এবং কোনও পৃষ্ঠার স্ক্রিপ্টের অন্তর্ভুক্ত না হয়ে।
অ্যান্ড্রেস রিওফ্রিও

5

আধুনিক ব্রাউজারগুলিতে আপনি নিম্নলিখিতগুলি করতে পারেন ...

button.addEventListener( 'click', () => {
    alert( 'only once!' );
}, { once: true } );

https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener# প্যারামিটার


আইআই বা প্রান্ত <16 এর কোনও সংস্করণ আসলে এই বৈশিষ্ট্যটিকে সমর্থন করে না এমনক্ষণ পর্যন্ত শীতল করুন। কমপক্ষে ৫ বছরে আমরা এটি ব্যবহার করতে পারি তার পর থেকে আইই (পড়ুন: উচিত) অবমূল্যায়ন করা হবে, এজটি তার জায়গা করে নেবে এবং এটি তাদের নিজস্ব "এজএইচটিএমএল" জিনিসটির পরিবর্তে ওয়েবকিট ইঞ্জিন ব্যবহার করবে।
সিডওফসি

4
ডিওএম লেভেল 4 এন্ট্রিগুলির জন্য এই পলিফিলের সাথে আপনার ভাল হওয়া উচিত npmjs.com/package/dom4
shunryu111

2

একটি বেনামে বিকল্প নয়

element.funky = function() {
    console.log("Click!");
};
element.funky.type = "click";
element.funky.capt = false;
element.addEventListener(element.funky.type, element.funky, element.funky.capt);
// blah blah blah
element.removeEventListener(element.funky.type, element.funky, element.funky.capt);

অ্যান্ডির কাছ থেকে প্রতিক্রিয়া গ্রহণ করার পরে ( বেশিরভাগ উদাহরণ হিসাবে, তবে আমি ধারণাটির প্রাসঙ্গিক প্রসার প্রদর্শন করতে চেয়েছি ), এখানে একটি জটিল জটিল বর্ণনা দেওয়া হয়েছে :

<script id="konami" type="text/javascript" async>
    var konami = {
        ptrn: "38,38,40,40,37,39,37,39,66,65",
        kl: [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ]
    };
    document.body.addEventListener( "keyup", function knm ( evt ) {
        konami.kl = konami.kl.slice( -9 );
        konami.kl.push( evt.keyCode );
        if ( konami.ptrn === konami.kl.join() ) {
            evt.target.removeEventListener( "keyup", knm, false );

            /* Although at this point we wish to remove a listener
               we could easily have had multiple "keyup" listeners
               each triggering different functions, so we MUST
               say which function we no longer wish to trigger
               rather than which listener we wish to remove.

               Normal scoping will apply to where we can mention this function
               and thus, where we can remove the listener set to trigger it. */

            document.body.classList.add( "konami" );
        }
    }, false );
    document.body.removeChild( document.getElementById( "konami" ) );
</script>

এটি কার্যকরভাবে বেনামে ফাংশন কাঠামোর অনুমতি দেয়, ব্যবহারিকভাবে অবহেলিত কলির ব্যবহার এড়িয়ে যায় এবং সহজে সরানোর অনুমতি দেয়।

ঘটনাক্রমে : শ্রোতা সেট করার সাথে সাথেই স্ক্রিপ্টের উপাদানটি অপসারণ হ'ল কোড লুকানোর জন্য একটি দুর্দান্ত কৌশল যা পছন্দ করবে চোখের ছাঁটাই একেবারেই সুস্পষ্ট নয় ( অবাক করে দেবে অবাক করে দেবে) ;-)

সুতরাং পদ্ধতিটি ( আরও সহজভাবে ):

element.addEventListener( action, function name () {
    doSomething();
    element.removeEventListener( action, name, capture );
}, capture );

4
এটি জটিলতার চেয়ে বেশি।
প্রোনবার্ড

@ অ্যান্ডি আমি একরকম, একমত, কিন্তু এটি দেখানোর চেষ্টা করছিলাম যে কোনও বেনামি ফাংশন সরানোর সহজ উপায় নেই। এটি অবশ্যই কোনওভাবে রেফারেন্স করা উচিত (এমনকি কলি (খারাপ, এম'কে) ফাংশনটি রেফারেন্স করছে), এবং এইভাবে ফাংশনটি রেফারেন্স করার জন্য কেবল একটি (অন্য) উপায়টির একটি উদাহরণ সরবরাহ করেছে - এবং, এটি কীভাবে অংশগুলির তৈরি পরবর্তী তথ্যসূত্রের জন্য সমানভাবে সংরক্ষণ করা যেতে পারে (গুরুত্বপূর্ণ অংশ)। স্পষ্টতই একটি সত্যিকারের বেনাম ফাংশনটি কিছুটা দ্য ফ্লাইয়ে তৈরি করা হয়েছে এবং তাই কোন ইভেন্টের ক্রিয়া / ধরন এবং ক্যাপচারটি ব্যবহৃত হয়েছিল তাও জেনে রাখা আবশ্যক। যাইহোক, এখানে একটি আরও ভাল পদ্ধতি :-)
ফ্রেড গ্যান্ট

আমার জন্য নিখুঁতভাবে কাজ করেছেন। আমি ফাংশনটিতে তর্কগুলি যুক্ত করার অন্য কোনও উপায় দেখতে পেলাম না, কারণ এটি অনামী হতে পারে না।
নিকোডেমাস 13

2

এটি আদর্শ না কারণ এটি সমস্ত সরিয়ে দেয় তবে এটি আপনার প্রয়োজনের জন্য কাজ করতে পারে:

z = document.querySelector('video');
z.parentNode.replaceChild(z.cloneNode(1), z);

একটি নোড ক্লোনিং এর সমস্ত বৈশিষ্ট্য এবং তাদের মানগুলি অনুলিপি (– লাইনে) সহ অনুলিপি করে। এটি ইভেন্ট শ্রোতাদের অ্যাডএভেন্টলিস্টনার () ব্যবহার করে অনুলিপি করে না

নোড.ক্লোননোড ()


এটি একেবারে উজ্জ্বল
আহমদ আলফী 19

1

জাভাস্ক্রিপ্ট : অ্যাডএভেন্টলিস্টনার পদ্ধতিটি ইভেন্ট স্ট্র্যাটে (এলিমেন্ট | ডকুমেন্ট | উইন্ডো) এর উপরে বর্ণিত শ্রোতাদের নিবন্ধ রেখেছে।

ইভেন্টট্যারেট addEventListener ( ইভেন্ট_প্রকার , হ্যান্ডলার_ফংশন, বুদবুদ | ক্যাপচারিং );

মাউস, কীবোর্ড ইভেন্টগুলি ওয়েবকনসোলের উদাহরণ পরীক্ষার:

var keyboard = function(e) {
    console.log('Key_Down Code : ' + e.keyCode);
};
var mouseSimple = function(e) {
    var element = e.srcElement || e.target;
    var tagName = element.tagName || element.relatedTarget;
    console.log('Mouse Over TagName : ' + tagName);    
};
var  mouseComplex = function(e) {
    console.log('Mouse Click Code : ' + e.button);
} 

window.document.addEventListener('keydown',   keyboard,      false);
window.document.addEventListener('mouseover', mouseSimple,   false);
window.document.addEventListener('click',     mouseComplex,  false);

অপসারণ অপসারণ- পদ্ধতি ইভেন্ট শ্রোতার পূর্বে ইভেন্টটিচারেট.এডএডএভেন্টলিস্টনার () এর সাথে নিবন্ধিত করে।

window.document.removeEventListener('keydown',   keyboard,     false);
window.document.removeEventListener('mouseover', mouseSimple,  false);
window.document.removeEventListener('click',     mouseComplex, false);

আমি ব্যবহার করতে পারেন


1

এটিতে আরও একটি আপ-টু-ডেট পদ্ধতির জন্য:

//one-time fire
element.addEventListener('mousedown', {
  handleEvent: function (evt) {
    element.removeEventListener(evt.type, this, false);
  }
}, false);

4
একটি ব্যাখ্যা ভাল হবে।
পৌল বক

1

আমি একই সমস্যা জুড়ে হোঁচট খেয়েছি এবং এটিই আমার পক্ষে সেরা সমাধান ছিল:

/*Adding the event listener (the 'mousemove' event, in this specific case)*/
element.onmousemove = function(event) {
    /*do your stuff*/
};
/*Removing the event listener*/
element.onmousemove = null;

দয়া করে মনে রাখবেন আমি এটির windowউপাদান এবং 'mousemove'ইভেন্টের জন্য কেবল এটি পরীক্ষা করেছি তাই এই পদ্ধতির সাথে কিছু সমস্যা হতে পারে।


0

আপনি যা জিজ্ঞাসা করছেন তার দিক থেকে সম্ভবত সেরা সমাধান নয়। ইভেন্ট শ্রোতার অনুরোধের সাথে ইনলাইন ঘোষিত বেনাম ফাংশন সরানোর জন্য আমি এখনও একটি কার্যকর পদ্ধতি নির্ধারণ করতে পারি নি।

<target>ইভেন্টের শ্রোতার অনুরোধের বাইরে ফাংশনটি সঞ্চয় করতে এবং ঘোষণা করতে আমি ব্যক্তিগতভাবে একটি পরিবর্তনশীল ব্যবহার করি যেমন:

const target = document.querySelector('<identifier>');

function myFunc(event) { function code; }

target.addEventListener('click', myFunc);

তারপরে শ্রোতাদের অপসারণ করতে:

target.removeEventListener('click', myFunc);

আপনি যে শীর্ষ প্রস্তাবনাটি গ্রহণ করবেন তা নয় তবে বেনামে ফাংশনগুলি সরিয়ে ফেলার জন্য আমার কেবলমাত্র কার্যকর সমাধানটি হ'ল এইচটিএমএল উপাদানটি প্রতিস্থাপন করুন। আমি নিশ্চিত যে আরও ভাল ভ্যানিলা জেএস পদ্ধতি থাকতে হবে তবে আমি এটি এখনও দেখিনি।


0

আমি জানি এটি মোটামুটি পুরানো থ্রেড, তবে আমি ভেবেছিলাম যারা এটি দরকারী মনে করেন তাদের জন্য আমি আমার দুটি সেন্ট স্থাপন করতে পারি।

স্ক্রিপ্ট (উদ্বেগহীন পদ্ধতির নামগুলির জন্য ক্ষমা):

window.Listener = {
    _Active: [],
    remove: function(attached, on, callback, capture){
        for(var i = 0; i < this._Active.length; i++){
            var current = this._Active[i];
            if(current[0] === attached && current[1] === on && current[2] === callback){
                attached.removeEventListener(on, callback, (capture || false));
                return this._Active.splice(i, 1);
            }
        }
    }, removeAtIndex(i){
        if(this._Active[i]){
            var remove = this._Active[i];
            var attached = remove[0], on = remove[1], callback = remove[2];
            attached.removeEventListener(on, callback, false);
            return this._Active.splice(i, 1);
        }
    }, purge: function(){
        for(var i = 0; i < this._Active.length; i++){
            var current = this._Active[i];
            current[0].removeEventListener(current[1], current[2]);
            this._Active.splice(i, 1);
        }
    }, declare: function(attached, on, callback, capture){
        attached.addEventListener(on, callback, (capture || false));
        if(this._Active.push([attached, on, callback])){
            return this._Active.length - 1;
        }
    }
};

এবং আপনি এটি এর মতো ব্যবহার করতে পারেন:

// declare a new onclick listener attached to the document
var clickListener = Listener.declare(document, "click" function(e){
    // on click, remove the listener and log the clicked element
    console.log(e.target);
    Listener.removeAtIndex(clickListener);
});

// completely remove all active listeners 
// (at least, ones declared via the Listener object)
Listener.purge();

// works exactly like removeEventListener
Listener.remove(element, on, callback);

-1

আমি কেবল অনুলিপি-সুরক্ষা ওয়ার্ডপ্রেস প্লাগইন সহ একযোগে সমস্যাটি অনুভব করেছি। কোডটি ছিল:

function disableSelection(target){
 if (typeof target.onselectstart!="undefined") //For IE 
  target.onselectstart=function(){return false}
 else if (typeof target.style.MozUserSelect!="undefined") //For Firefox
  target.style.MozUserSelect="none"
 else //All other route (For Opera)
  target.onmousedown=function(){return false}
target.style.cursor = "default"
}

এবং তারপরে এটি আলগাভাবে রেখে শুরু করা হয়েছিল

<script type="text/javascript">disableSelection(document.body)</script>.

আমি কেবল এই ইভেন্টে অন্যান্য বেনামে ফাংশন সংযুক্ত করে এটিকে ঘিরে এসেছি:

document.body.onselectstart = function() { return true; };

-4
window.document.onkeydown = function(){};

কেন = অপরিবর্তিত? বাস্তব খারাপ
প্রোনবার্ড

4
এটি নিবন্ধিত হওয়া কোনও হ্যান্ডলার সরিয়ে ফেলবে না addEventListener
Luc125
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.