programing

특정 유형의 모든 이벤트청취자 삭제

bestcode 2022. 10. 18. 22:52
반응형

특정 유형의 모든 이벤트청취자 삭제

다음을 사용하여 추가된 특정 유형의 모든 이벤트 청취자를 제거합니다.addEventListener()모든 리소스에서 이 작업을 수행할 필요가 있다고 합니다.

elem.addEventListener('mousedown',specific_function);
elem.removeEventListener('mousedown',specific_function);

다만, 다음과 같이, 현재의 상태를 파악하지 않고 클리어 할 수 있도록 하고 싶습니다.

elem.addEventListener('mousedown',specific_function);
elem.removeEventListener('mousedown');

그것은 가로채기 없이는 불가능하다.addEventListener불행히도 이러한 기능을 사용할 수 있는 라이브러리를 사용합니다.청취자 컬렉션에 액세스할 수 있지만 기능이 구현되지 않은 경우입니다.

가장 가까운 방법은 요소를 복제하여 모든 청취자를 제거하는 것입니다. 그러면 청취자 컬렉션은 복제되지 않습니다.

참고: 이렇게 하면 요소의 자식 청취자도 제거됩니다.

var el = document.getElementById('el-id'),
    elClone = el.cloneNode(true);

el.parentNode.replaceChild(elClone, el);

리스너를 삭제함으로써 리스너의 실행을 정지하는 것이 유일한 목표인 경우 지정된 유형의 모든 이벤트를 캡처하여 취소할 수 있습니다.

window.addEventListener(type, function(event) {
    event.stopImmediatePropagation();
}, true);

패스인true세 번째 파라미터의 경우 이벤트가 다운될 때 캡처됩니다.전파를 정지한다는 것은 이벤트가 수신 중인 청취자에게 도달하지 않는다는 것을 의미합니다.

지정된 유형에 대해 새 수신기를 추가할 수 없으므로 이 수신기는 매우 제한적입니다(모든 수신기가 차단됩니다.예를 들어 듣는 사람만이 들을 수 있는 새로운 종류의 이벤트를 개최함으로써 이 문제를 어느 정도 해결할 수 있는 방법이 있습니다.그 방법은 다음과 같습니다.

window.addEventListener('click', function (event) {
    // (note: not cross-browser)
    var event2 = new CustomEvent('click2', {detail: {original: event}});
    event.target.dispatchEvent(event2);
    event.stopPropagation();
}, true);

element.addEventListener('click2', function(event) {
    if (event.detail && event.detail.original) {
        event = event.detail.original
    }
    // Do something with event
});

단, 마우스 이동과 같은 고속 이벤트에서는 이벤트를 재디스패치하면 지연이 발생하기 때문에 이 방법은 동작하지 않을 수 있습니다.

이 작업을 해야 할 경우에는 Martin Wantke의 답변에 설명된 대로 처음에 추가된 청취자를 추적하는 것이 좋습니다.

모든 'add listener' 호출을 기록하기 위한 트랩 함수를 구축하려면 EventTarget.protype.addEventListener를 재정의해야 합니다.다음과 같은 경우:

var _listeners = [];

EventTarget.prototype.addEventListenerBase = EventTarget.prototype.addEventListener;
EventTarget.prototype.addEventListener = function(type, listener)
{
    _listeners.push({target: this, type: type, listener: listener});
    this.addEventListenerBase(type, listener);
};

그런 다음 EventTarget.protype.removeEventListeners를 구축할 수 있습니다.

EventTarget.prototype.removeEventListeners = function(targetType)
{
    for(var index = 0; index != _listeners.length; index++)
    {
        var item = _listeners[index];

        var target = item.target;
        var type = item.type;
        var listener = item.listener;

        if(target == this && type == targetType)
        {
            this.removeEventListener(type, listener);
        }
    }
}

ES6에서 기호를 사용하여 인스턴스화된 객체 자체에서 직접 원래 기능과 추가된 모든 수신기 목록을 숨길 수 있습니다.

(function()
{
    let target = EventTarget.prototype;
    let functionName = 'addEventListener';
    let func = target[functionName];

    let symbolHidden = Symbol('hidden');

    function hidden(instance)
    {
        if(instance[symbolHidden] === undefined)
        {
            let area = {};
            instance[symbolHidden] = area;
            return area;
        }

        return instance[symbolHidden];
    }

    function listenersFrom(instance)
    {
        let area = hidden(instance);
        if(!area.listeners) { area.listeners = []; }
        return area.listeners;
    }

    target[functionName] = function(type, listener)
    {
        let listeners = listenersFrom(this);

        listeners.push({ type, listener });

        func.apply(this, [type, listener]);
    };

    target['removeEventListeners'] = function(targetType)
    {
        let self = this;

        let listeners = listenersFrom(this);
        let removed = [];

        listeners.forEach(item =>
        {
            let type = item.type;
            let listener = item.listener;

            if(type == targetType)
            {
                self.removeEventListener(type, listener);
            }
        });
    };
})();

이 코드를 테스트하려면 , 다음의 작은 스니퍼를 사용합니다.

document.addEventListener("DOMContentLoaded", event => { console.log('event 1'); });
document.addEventListener("DOMContentLoaded", event => { console.log('event 2'); });
document.addEventListener("click", event => { console.log('click event'); });

document.dispatchEvent(new Event('DOMContentLoaded'));
document.removeEventListeners('DOMContentLoaded');
document.dispatchEvent(new Event('DOMContentLoaded'));
// click event still works, just do a click in the browser

글로벌 이벤트에서 모든 수신기 제거

element.onmousedown = null;

이제 다시 이벤트 청취자 추가로 돌아갈 수 있습니다.

element.addEventListener('mousedown', handler, ...);

이 솔루션은 "글로벌" 이벤트에서만 작동합니다.사용자 지정 이벤트가 작동하지 않습니다.다음은 모든 글로벌 이벤트 목록입니다.https://developer.mozilla.org/en-US/docs/Web/API/GlobalEventHandlers

건 요. 것을 요.keydown문서의 이벤트 리스너.그것들을 제거하는 것이 , 그것을 .addEventListener다른 스크립트가 로드되기 전에 이 스크립트를 추가함으로써 위의 Toms 답변과 마찬가지로 추가도 전에 무시합니다.

<script type="text/javascript">
    var current = document.addEventListener;
    document.addEventListener = function (type, listener) {
        if(type =="keydown")
        {
            //do nothing
        }
        else
        {
            var args = [];
            args[0] = type;
            args[1] = listener;
            current.apply(this, args);
        }
    };
</script>

요소의 모든 청취자를 한 줄씩 제거합니다.

element.parentNode.innerHTML += '';

원래 기능을 참조하지 않고 이벤트청취자를 삭제하는 최신 방법은 AbortController를 사용하는 것입니다.경고는 사용자가 직접 추가한 청취자만 중단할 수 있다는 것입니다.

const buttonOne = document.querySelector('#button-one');
const buttonTwo = document.querySelector('#button-two');
const abortController = new AbortController();

// Add multiple click event listeners to button one
buttonOne.addEventListener(
  'click',
  () => alert('First'),
  { signal: abortController.signal }
);

buttonOne.addEventListener(
  'click',
  () => alert('Second'),
  { signal: abortController.signal }
);

// Add listener to remove first button's listeners
buttonTwo.addEventListener(
  'click',
  () => abortController.abort()
);
<p>The first button will fire two alert dialogs when clicked. Click the second button to remove those listeners from the first button.</p>

<button type="button" id="button-one">Click for alerts</button>
<button type="button" id="button-two">Remove listeners</button>

되어 있는지 모르는 는 윈도 주위에 수 .addEventListener하여 청취자를 할 수 .removeAllEventListener('scroll')예를들면.

var listeners = {};

var originalEventListener = window.addEventListener;
window.addEventListener = function(type, fn, options) {
    if (!listeners[type])
        listeners[type] = [];

    listeners[type].push(fn);
    return originalEventListener(type, fn, options);
}

var removeAllEventListener = function(type) {
    if (!listeners[type] || !listeners[type].length)
        return;

    for (let i = 0; i < listeners[type].length; i++)
        window.removeEventListener(type, listeners[type][i]);
}

하나의 이벤트를 제거할 수는 없지만? 한 번에?그냥 하다

document.body.innerHTML = document.body.innerHTML

따라서 이 함수는 요소에서 지정된 수신기 유형의 대부분을 제거합니다.

function removeListenersFromElement(element, listenerType){
  const listeners = getEventListeners(element)[listenerType];
  let l = listeners.length;
  for(let i = l-1; i >=0; i--){
    removeEventListener(listenerType, listeners[i].listener);
  }
 }

어떤 이유로든 제거할 수 없는 드문 예외가 몇 가지 있었습니다.

대신 yourElement.addEventListener() 메서드를 덮어쓰고 .apply() 메서드를 사용하여 리스너를 정상적으로 실행하지만 프로세스에서 함수를 가로챌 수도 있습니다.예를 들어 다음과 같습니다.

<script type="text/javascript">

    var args = [];
    var orginalAddEvent = yourElement.addEventListener;

    yourElement.addEventListener = function() {
        //console.log(arguments);
        args[args.length] = arguments[0];
        args[args.length] = arguments[1];
        orginalAddEvent.apply(this, arguments);
    };

    function removeListeners() {
        for(var n=0;n<args.length;n+=2) {
            yourElement.removeEventListener(args[n], args[n+1]);
        }
    }

    removeListeners();

</script>

이 스크립트는 페이지 로드 시 실행해야 합니다.그렇지 않으면 모든 이벤트청취자를 가로채지 못할 수 있습니다.

사용하기 전에 반드시 'remove Listeners()' 호출을 삭제하십시오.

 var events = [event_1, event_2,event_3]  // your events

//make a for loop of your events and remove them all in a single instance

 for (let i in events){
    canvas_1.removeEventListener("mousedown", events[i], false)
}

언급URL : https://stackoverflow.com/questions/19469881/remove-all-event-listeners-of-specific-type

반응형