[javascript] 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하며 코드에서 사용할 수 없습니다 : 링크


답변

최신 브라우저에서는 다음을 수행 할 수 있습니다.

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

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


답변

익명이 아닌 옵션

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

Andy 로부터 피드백받은 이후 ( 아주 맞지만 많은 예에서와 같이 아이디어의 맥락 적 확장을 보여주고 싶었습니다 ), 여기에 덜 복잡한 설명이 있습니다.

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

이것은 효과적으로 익명의 함수 구조를 허용하고 실질적으로 사용되지 않는 callee의 사용을 하며 쉽게 제거 할 수 있습니다.

덧붙여 즉시 리스너를 설정 한 후 스크립트 요소의 제거는 (선호하는 코드를 숨기는 귀여운 트릭 캐고 눈에 굳어 지 분명하지 않았다이다 놀라움을 망칠 것 😉

따라서 방법 ( 보다 간단하게 )은 다음과 같습니다.

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


답변

이것은 모든 것을 제거하므로 이상적이지는 않지만 필요에 따라 작동 할 수 있습니다.

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

노드를 복제하면 내장 (인라인) 리스너를 포함하여 모든 속성과 해당 값이 복사됩니다. addEventListener ()를 사용하여 추가 된 이벤트 리스너는 복사하지 않습니다.

Node.cloneNode ()