Is there a vanilla function to remove all event listeners without affecting descendant threads?

This question is what I ask, but with the restriction not to delete events for descendant nodes.

In this fiddle, I am trying to remove connected listeners by deleting it from the DOM and returning it.

function removeListeners(el) { var par = el.parentNode; var place = el.nextSibling; par.removeChild(el); par.insertBefore(el, place); } 

Unfortunately, this did not work, you can still click to change the background (which is actually good, I never knew that you can attach events without an element located in the DOM).

Given this discovery, I tried this

 function removeListeners(el) { var par = el.parentNode; var clone = el.cloneNode(false); par.replaceChild(clone, el); for (var index = 0; index < el.childNodes.length; ++index) clone.appendChild(el.childNodes[index]); } 

Which tries to make a small clone, and then copies all the signatures, but does not copy all the child elements.

the above answer to the question said that "[if you want the children to keep their listeners], you will have to resort to explicitly removing the listeners one at a time." I do not know how you implement this.
I assume that it means getting a list of event types and removing listeners for each in turn ( as jQuery can ). Not only is this not possible for custom events , but vanilla JS has no such functions (you must specify a function to delete).

+4
source share
2 answers

I managed to complete my second attempt.
And then, thanks to @JulianDescottes, noting my supervision, I made this more concise version.

Here is the working code.

 function removeListeners(el) { //only replace the ancestor element var clone = el.cloneNode(false); //copy children backwards because of the removal for (var index = el.childNodes.length - 1; index >= 0; --index) clone.insertBefore(el.childNodes[index], clone.firstChild); //insert back into DOM el.parentNode.replaceChild(clone, el); } 

I was hoping for something more familiar, I'm afraid that unforeseen consequences will arise with the help of this method, I don’t like deleting things from the DOM and expecting them to work properly after.
At least this is more efficient than current offers, and if someone comes up with something more pleasant, I would be obliged (and grateful) to accept your answer.

0
source

Node.childNodes is not an array, but a NodeList (see NodeList on MDN ). It updates dynamically when updating the DOM.

In your case, you released the childNodes collection when you moved items to the new parentNode.

You can either copy the child Array.prototype.slice into an array using Array.prototype.slice , or iterate back.

 function removeListeners(el) { var par = el.parentNode; var clone = el.cloneNode(false); par.replaceChild(clone, el); for (var index = el.childNodes.length - 1; index >= 0; --index) clone.insertBefore(el.childNodes[index], clone.childNodes[0]); } 
+5
source

Source: https://habr.com/ru/post/1500853/


All Articles