Programing

JavaScript의 익명 함수에 대한 removeEventListener

lottogame 2020. 9. 15. 19:07
반응형

JavaScript의 익명 함수에 대한 removeEventListener


메서드가있는 개체가 있습니다. 이러한 메서드는 익명 함수 내부의 개체에 배치됩니다. 다음과 같이 보입니다.

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

(더 많은 코드가 있지만 문제를 보여주기에는 충분합니다)

이제 경우에 따라 이벤트 리스너를 중지하고 싶습니다. 따라서 removeEventListener를 시도하고 있지만 어떻게해야할지 알 수 없습니다. 익명 함수에서 removeEventListener를 호출 할 수 없다는 다른 질문을 읽었지만이 상황에서도 마찬가지입니까?

익명 함수 내부에 생성 된 메서드가 있으므로 가능하다고 생각했습니다. 다음과 같이 보입니다.

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

왜 이렇게 할 수 없습니까?

이 작업을 수행하는 다른 (좋은) 방법이 있습니까?

보너스 정보; 이것은 Safari에서만 작동하므로 IE 지원이 누락되었습니다.


나는 그것이 익명의 기능의 요점이라고 믿으며 이름이나 참조 방법이 부족합니다.

내가 당신이라면 명명 된 함수를 만들거나 변수에 넣어서 참조 할 수 있습니다.

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

실제 함수 내부에 있으면 arguments.callee를 함수에 대한 참조로 사용할 수 있습니다. 다음과 같이 :

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

편집 : 엄격 모드 ( "use strict";) 에서 작업하는 경우 작동하지 않습니다.


Strict 모드에서 작동하는 Otto Nascarella 솔루션 의 버전 은 다음과 같습니다.

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

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

여러 익명 기능이 될 수 있습니다, keydown 1

경고 : 코드에서만 작동 Chrome Dev Tools하며 코드에서 사용할 수 없습니다 : 링크


익명이 아닌 옵션

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

Since receiving feedback from Andy (quite right, but as with many examples, I wished to show a contextual expansion of the idea), here's a less complicated exposition:

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

This allows an effectively anonymous function structure, avoids the use of the practically deprecated callee, and allows easy removal.

Incidentally: The removal of the script element immediately after setting the listener is a cute trick for hiding code one would prefer wasn't starkly obvious to prying eyes (would spoil the surprise ;-)

So the method (more simply) is:

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

This is not ideal as it removes all, but might work for your needs:

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

Cloning a node copies all of its attributes and their values, including intrinsic (in–line) listeners. It does not copy event listeners added using addEventListener()

Node.cloneNode()


in modern browsers you can to the following...

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

https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener#Parameters


JavaScript: addEventListener method registers the specified listener on the EventTarget(Element|document|Window) it's called on.

EventTarget.addEventListener(event_type, handler_function, Bubbling|Capturing);

Mouse, Keyboard events Example test in WebConsole:

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

removeEventListener method removes the event listener previously registered with EventTarget.addEventListener().

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

caniuse


To give a more up-to-date approach to this:

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

Possibly not the best solution in terms of what you are asking. I have still not determined an efficient method for removing anonymous function declared inline with the event listener invocation.

I personally use a variable to store the <target> and declare the function outside of the event listener invocation eg:

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

function myFunc(event) { function code; }

target.addEventListener('click', myFunc);

Then to remove the listener:

target.removeEventListener('click', myFunc);

Not the top recommendation you will receive but to remove anonymous functions the only solution I have found useful is to remove then replace the HTML element. I am sure there must be a better vanilla JS method but I haven't seen it yet.


I have stumbled across the same problem and this was the best solution I could get:

/*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;

Please keep in mind I have only tested this for the window element and for the 'mousemove' event, so there could be some problems with this approach.


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

참고URL : https://stackoverflow.com/questions/4950115/removeeventlistener-on-anonymous-functions-in-javascript

반응형