How to detect element being added/removed from dom element?
Use Mutation Observers as suggested by @Qantas in his answer
Following methods are deprecated
You can use DOMNodeInserted and DOMNodeRemoved
$("#parent").on('DOMNodeInserted', function(e) {
console.log(e.target, ' was inserted');
});
$("#parent").on('DOMNodeRemoved', function(e) {
console.log(e.target, ' was removed');
});
MDN Docs
DOM event when element is removed
There's a HTML5 API called MutationObserver and it has pretty good support
Here's an example:
// Element is the whatever subtree/element you need to watch over
var in_dom = document.body.contains(element);
var observer = new MutationObserver(function(mutations) {
if (document.body.contains(element)) {
if (!in_dom) {
console.log("element inserted");
}
in_dom = true;
} else if (in_dom) {
in_dom = false;
console.log("element removed");
}
});
observer.observe(document.body, {childList: true, subtree: true});
Detect that given element has been removed from the DOM without sacrificing performance
As you said, MutationObserver
only allows you to detect when the children of an element are manipulated. That means you'll need to listen to the parent and check what changes were made to see if the target element was removed.
function onRemove(element, callback) {
const parent = element.parentNode;
if (!parent) throw new Error("The node must already be attached");
const obs = new MutationObserver(mutations => {
for (const mutation of mutations) {
for (const el of mutation.removedNodes) {
if (el === element) {
obs.disconnect();
callback();
}
}
}
});
obs.observe(parent, {
childList: true,
});
}
then with your example instead of
element.onRemove(() => releaseKraken(element));
you can do
onRemove(element, () => releaseKraken(element));
This approach should be plenty fast if all you are doing is watching a single element. While it may seem like a decent amount of looping, it is pretty rare for removedNodes
to be more than one node, and unless something is removing tons of siblings all at once, mutations
is going to be quite small too.
You could also consider doing
callback(el);
which would allow you to do
onRemove(element, releaseKraken);
Detect when a node is deleted (or removed from the DOM because a parent was)
Here is an implementation that identifies how the element was removed (either directly or because a parent was removed)
var target = document.querySelector('#to-be-removed');
var observer = new MutationObserver(function(mutations) { // check for removed target mutations.forEach(function(mutation) { var nodes = Array.from(mutation.removedNodes); var directMatch = nodes.indexOf(target) > -1 var parentMatch = nodes.some(parent => parent.contains(target)); if (directMatch) { console.log('node', target, 'was directly removed!'); } else if (parentMatch) { console.log('node', target, 'was removed through a removed parent!'); }
});});
var config = { subtree: true, childList: true};observer.observe(document.body, config);
var qs = document.querySelector.bind(document);qs('#ul').addEventListener('click', function(){qs('ul').remove();}, false)qs('#li').addEventListener('click', function(){qs('#to-be-removed').remove();}, false)
<ul> <li>list item 1</li> <li>list item 2</li> <li id="to-be-removed">list item 3</li> <li>list item 4</li></ul>
<button id="ul">remove ul</button><button id="li">remove li</button>
javascript detect when a certain element is removed
In most modern browsers you can use the MutationObserver to achieve this.
The way you would do it would be something like this:
var parent = document.getElementById('parent');var son = document.getElementById('son');
console.log(parent);var observer = new MutationObserver(function(mutations) { mutations.forEach(function(mutation) { console.log(mutation); // check if your son is the one removed });});
// configuration of the observer:var config = { childList: true};
observer.observe(parent, config);
son.remove();
How can I be notified when an element is added to the page?
Warning!
This answer is now outdated. DOM Level 4 introduced MutationObserver, providing an effective replacement for the deprecated mutation events. See this answer to another question for a better solution than the one presented here. Seriously. Don't poll the DOM every 100 milliseconds; it will waste CPU power and your users will hate you.
Since mutation events were deprecated in 2012, and you have no control over the inserted elements because they are added by someone else's code, your only option is to continuously check for them.
function checkDOMChange()
{
// check for any new element being inserted here,
// or a particular node being modified
// call the function again after 100 milliseconds
setTimeout( checkDOMChange, 100 );
}
Once this function is called, it will run every 100 milliseconds, which is 1/10 (one tenth) of a second. Unless you need real-time element observation, it should be enough.
Destroy hook when HTML elements are removed
Yes, there is. Although you will need either jQuery UI or to write your own special event. The problem is it only works if the element is removed using jQuery. Aside from that, you would need to use DOM events or the recommended solution - DOM Mutation Observers.
These questions should help you further:
- jQuery - Trigger event when an element is removed from the DOM
- How to detect element being added/removed from dom element?
By the way, that is the keyword you missed - "event". That's what these "hooks" are called in jQuery/DOM.
Related Topics
React-Router - Pass Props to Handler Component
How to Tell If Caps Lock Is on Using JavaScript
Remove All Elements Contained in Another Array
Add a "Hook" to All Ajax Requests on a Page
Array VS. Object Efficiency in JavaScript
Accessing Redux State in an Action Creator
Getting a Better Understanding of Callback Functions in JavaScript
How to Implement Routereusestrategy Shoulddetach for Specific Routes in Angular 2
What's the Fastest Way to Loop Through an Array in JavaScript
What Does [].Foreach.Call() Do in JavaScript
Event When Window.Location.Href Changes
How to Get Jquery to Select Elements with a . (Period) in Their Id
Determine Original Size of Image Cross Browser
Es6 Variable Import Name in Node.Js
JavaScript Require() Function Giving Referenceerror: Require Is Not Defined
How to Make JavaScript Object Using a Variable String to Define the Class Name
Iterate Through Nested JavaScript Objects
React: Script Tag Not Working When Inserted Using Dangerouslysetinnerhtml