How to Clear/Remove JavaScript Event Handler

How to Clear/Remove JavaScript Event Handler?

To do this without any libraries:

document.getElementById("aspnetForm").onsubmit = null;

Is it possible to remove all event handlers of a given element in javascript?

http://www.quirksmode.org/js/events_advanced.html - "Which event handlers are registered?" - it seems it's not possible without DOM 3 level :-(

EDIT: I've come up with this code. It suits my needs. Maybe it will be helpful for someone else.

Javascript:

function DomLib() {

}

/**
* Based on: http://ejohn.org/blog/flexible-javascript-events/
* Function that register event and enables it to be removed without explicitly giving the function definition
*/
DomLib.prototype.regEventEx = function (el, eventName, funct) {

if (el.attachEvent) {
el['e'+eventName+funct] = funct;
el[eventName+funct] = function(){el['e'+eventName+funct](window.event);}
el.attachEvent( 'on'+eventName, el[eventName+funct] );
} else {
el.addEventListener(eventName, funct, false);
}

if(!el.eventHolder) el.eventHolder = [];
el.eventHolder[el.eventHolder.length] = new Array(eventName, funct);
}

DomLib.prototype.removeEvent = function (obj, type, fn) {
if (obj.detachEvent) {
obj.detachEvent( 'on'+type, obj[type+fn] );
obj[type+fn] = null;
} else {
obj.removeEventListener( type, fn, false );
}
}

DomLib.prototype.hasEventEx = function (el, eventName, funct) {

if (!el.eventHolder) {
return false;
} else {
for (var i = 0; i < el.eventHolder.length; i++) {
if (el.eventHolder[i][0] == eventType && String(el.eventHolder[i][1]) == String(funct)) {
return true;
}
}
}
return false;
}

/**
* @return - returns true if an event was removed
*/
DomLib.prototype.removeEventsByTypeEx = function (el, eventType) {

if (el.eventHolder) {

var removed = 0;
for (var i = 0; i < el.eventHolder.length; i++) {
if (el.eventHolder[i][0] == eventType) {
this.removeEvent(el, eventType, el.eventHolder[i][1]);
el.eventHolder.splice(i, 1);
removed++;
i--;
}
}

return (removed > 0) ? true : false;
} else {
return false;
}
}

Testing HTML page:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<meta http-equiv="Expires" content="Fri, Jan 01 1900 00:00:00 GMT">
<meta http-equiv="Pragma" content="no-cache">
<meta http-equiv="Cache-Control" content="no-cache">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta http-equiv="Lang" content="en">
<meta name="author" content="">
<meta http-equiv="Reply-to" content="@.com">
<meta name="generator" content="PhpED 5.8">
<meta name="description" content="">
<meta name="keywords" content="">
<meta name="creation-date" content="01/01/2009">
<meta name="revisit-after" content="15 days">
<title>DomLibTest</title>
<link rel="stylesheet" type="text/css" href="my.css">
<!-- FILL IN: Location of your jQuery library -->
<script type="text/javascript" src="jQuery/jQuery-current.js"></script>
<!-- FILL IN: Plugin for debugging ... http://www.ecitadel.net/blog/2009/12/08/developing-jquery-use-dump-instead-alert -->
<script type="text/javascript" src="jQuery/jQuery.dump.js"></script>
<script type="text/javascript" src="DomLib.js"></script>
</head>
<body>

<div id="testElem-1"></div>
<script type="text/javascript">
<!--

var domLib = new DomLib();

function removeTest(el) {

var funct = function() { alert("#1: How Are You?");};
var funct2 = function() { alert("#2: How Are You?");};

domLib.regEventEx(el, "click", funct);
domLib.regEventEx(el, "mousemove", funct2);
domLib.regEventEx(el, "mousemove", funct2);
domLib.regEventEx(el, "mousemove", funct2);

$.dump(el.eventHolder);
domLib.removeEventsByTypeEx(el, "mousemove");
$.dump(el.eventHolder);
}

removeTest(document.getElementById('testElem-1'));

-->
</script>
</body>
</html>

How can I remove an event listener in JavaScript?

You have to pass the same function to removeEventListener that you passed to addEventListener. The function you are passing to addEventListener is

(e) => {
switch(e.keyCode) {
case 37: //left arrow key
console.log("left")
break
case 39:
console.log("right")
break
}
}

Since you are not storing a reference to it anywhere you cannot remove it. Assign that function to variable and use that to add and remove it:

const start = document.querySelector(".start")
const stopbtn = document.querySelector(".stop")

function handleKey(e) {
switch (e.keyCode) {
case 37: //left arrow key
console.log("left")
break
case 39:
console.log("right")
break
}
}

function keyboardControl() {
document.addEventListener("keydown", handleKey);
}

start.addEventListener("click", () => keyboardControl())
stopbtn.addEventListener(
"click",
() => document.removeEventListener("keydown", handleKey)
)
<button class="start">start</button>
<button class="stop">stop</button>

Remove event handler function from window?

You cannot remove a specific anonymous event handler from an object when using the onEVENT syntax. Whenever you call object.onclick =, you overwrite whatever is currently assigned to the onclick property of object.

You will need to use addEventListener() and removeEventListener() with a named function:

function windowClicker(event) 
{
if (event.target == modal)
{
modal.style.display = "none";
}
}

// Add the listener:
window.addEventListener('click', windowClicker, false);

// Remove it:
window.removeEventListener('click', windowClicker, false);

Removing an anonymous event listener

There is no way to cleanly remove an event handler unless you stored a reference to the event handler at creation.

I will generally add these to the main object on that page, then you can iterate and cleanly dispose of them when done with that object.

Javascript/DOM: How to remove all event listeners of a DOM object?

I am not sure what you mean with remove all events. Remove all handlers for a specific type of event or all event handlers for one type?

Remove all event handlers

If you want to remove all event handlers (of any type), you could clone the element and replace it with its clone:

var clone = element.cloneNode(true);

Note: This will preserve attributes and children, but it will not preserve any changes to DOM properties.



Remove "anonymous" event handlers of specific type

The other way is to use removeEventListener() but I guess you already tried this and it didn't work. Here is the catch:

Calling addEventListener to an anonymous function creates a new listener each time. Calling removeEventListener to an anonymous function has no effect. An anonymous function creates a unique object each time it is called, it is not a reference to an existing object though it may call one. When adding an event listener in this manner be sure it is added only once, it is permanent (cannot be removed) until the object it was added to, is destroyed.

You are essentially passing an anonymous function to addEventListener as eventReturner returns a function.

You have two possibilities to solve this:

  1. Don't use a function that returns a function. Use the function directly:

     function handler() {
    dosomething();
    }

    div.addEventListener('click',handler,false);
  2. Create a wrapper for addEventListener that stores a reference to the returned function and create some weird removeAllEvents function:

     var _eventHandlers = {}; // somewhere global

    const addListener = (node, event, handler, capture = false) => {
    if (!(event in _eventHandlers)) {
    _eventHandlers[event] = []
    }
    // here we track the events and their nodes (note that we cannot
    // use node as Object keys, as they'd get coerced into a string
    _eventHandlers[event].push({ node: node, handler: handler, capture: capture })
    node.addEventListener(event, handler, capture)
    }

    const removeAllListeners = (targetNode, event) => {
    // remove listeners from the matching nodes
    _eventHandlers[event]
    .filter(({ node }) => node === targetNode)
    .forEach(({ node, handler, capture }) => node.removeEventListener(event, handler, capture))

    // update _eventHandlers global
    _eventHandlers[event] = _eventHandlers[event].filter(
    ({ node }) => node !== targetNode,
    )
    }

And then you could use it with:

    addListener(div, 'click', eventReturner(), false)
// and later
removeAllListeners(div, 'click')

DEMO

Note: If your code runs for a long time and you are creating and removing a lot of elements, you would have to make sure to remove the elements contained in _eventHandlers when you destroy them.

How to remove event listeners created dynamically from respective elemets?

You need to pass in the same handler in removeEventListener that you are passing in addEventListener

const handler = () => doSomeThing()

element.addEventListener("click", handler)

// Then remove them like this.
element.removeEventListener("click", handler)

Since you are creating a new function every time you loop, store those handlers in an array and use the same handlers in the removeListener for each element.

Since the logic of the handlers are same for all elements you can do this:

const modalHandler = (evt) => {
togglePopup(evt.target);
};

const keyDownHandler = (evt) => {
const escKey = 27;
if (evt.keyCode === escKey) {
togglePopup(document.querySelector(".popup_active"));
}
};

const togglePopupAlt = () => {
const popupList = Array.from(document.querySelectorAll(".popup"));
popupList.forEach((modal) => {
modal.addEventListener("click", modalHandler);
});
popupList.forEach((modal) => {
modal.removeEventListener("click", modalHandler);
});

popupList.forEach(() => {
document.addEventListener("keydown", keyDownHandler);
document.removeEventListener("keydown", keyDownHandler);
});
};

togglePopupAlt();


Related Topics



Leave a reply



Submit