I'm adding some element to DOM after drag event. I need to detect this element and the moment when this element was added. I use Mutation Observer but something is wrong, the code:
var targetNodes = $('.mvly');
var MutationObserver = window.MutationObserver || window.WebKitMutationObserver;
var myObserver = new MutationObserver (mutationHandler);
var obsConfig = { childList: true, characterData: true, attributes: true, subtree: true };
targetNodes.each(function(){
myObserver.observe(this, obsConfig);
} );
function mutationHandler (mutationRecords) {
mutationRecords.forEach ( function (mutation) {
if (typeof mutation.addedNodes == "object") {
console.log('test');
}
});
}
Can anybody help, much thx.
Here's a simple example of how you can use a MutationObserver to listen for when an element is added to the DOM.
For brevity, I'm using jQuery syntax to build the node and insert it into the DOM.
var myElement = $("<div>hello world</div>")[0];
var observer = new MutationObserver(function(mutations) {
if (document.contains(myElement)) {
console.log("It's in the DOM!");
observer.disconnect();
}
});
observer.observe(document, {attributes: false, childList: true, characterData: false, subtree:true});
$("body").append(myElement); // console.log: It's in the DOM!
You don't need to iterate over each MutationRecord stored in mutations because you can perform the document.contains check directly upon myElement.
Related
I read about The MutationObserver function or I think it is an interface
but I can't use it
Can anyone tell me?
var MutationObserver = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver;
var observer = new MutationObserver(function(mutations) {
mutations.forEach(function(mutation) {
console.log("new element has been added");
console.log(mutation.target.nodeName);
});
});
Of course, MutationObserver is an interface but you need to call the observe() function in order to detect any change in the DOM:
observer.observe(targetNode, observerOptions);
You can try adding this to your code:
observer.observe(document, {attributes: true, childList: true, characterData: false, subtree:true});
I'm adding a new element dynamically via JQuery, with code like the below:
$('#example').after("<p class='xx'></p>")
Upon this code being called and a "xx" element being added, I'd like to run some other code. How can I 'listen' and pick up when this event happens?
Thanks
You can use Mutation Observer for this.
The demo below is a simple quick adaptation of the example in reference.
$(document).ready(function(){
var targetNode = document.getElementById('some-id');
var config = { attributes: true, childList: true, subtree: true };
var callback = function(mutationsList, observer) {
for(var mutation of mutationsList) {
if (mutation.type == 'childList') {
console.log('A child node has been added or removed.');
}
}
};
var observer = new MutationObserver(callback);
observer.observe(targetNode, config);
$('#example').after("<p class='xx'>I am a paragraph inserted by a script.</p>");
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="some-id">
<p id="example">I'm a static paragraph.</p>
</div>
Hi,
I need to execute a javascript function once as soon as an element with a given class appears on the code (the element will be generated by another script).
This is my function:
play(sound);
the element would appear inside this:
<div id="canvas">
The element would look like this:
<span class="sound">sound name</span>
where "sound name" will determine the argument for play();
how can this be done with javascript?
Thank you.
You can use a You could use a MutationObserver as shown below.
The second argument to .observe(), MutationObserverInit, is important:
In the options, use childList: true if the span will only be added as a direct child. subTree: true if it can be at any level down below #canvas.
From the docs:
childList: Set to true if additions and removals of the target node's child elements (including text nodes) are to be observed.
subtree: Set to true if mutations to target and target's descendants are to be observed.
$("#go").click(function () {
$("#canvas").append($('<span class="sound">sound name</span>'));
});
function play(n) { alert('playing '+ n); }
var obs = new MutationObserver(function(mutations, observer) {
$.each(mutations, function (i, mutation) {
var addedNodes = $(mutation.addedNodes);
var selector = "span.sound"
var spanSounds = addedNodes.find(selector).addBack(selector); // finds either added alone or as tree
spanSounds.each(function () { // handles any number of added spans
play($(this).text());
});
});
});
obs.observe($("#canvas")[0], {childList: true, subtree: true});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="canvas"></div>
<button id="go">Add span to canvas</button>
Using plain JavaScript
The code is a little less compact, but it is definitely doable:
document.getElementById("go").addEventListener('click', function () {
var s = document.createElement('span');
s.innerText = 'sound name';
s.classList.add('sound')
document.getElementById('canvas').appendChild(s);
});
function play(n) { alert('playing '+ n); }
var obs = new MutationObserver(function(mutations, observer) {
for(var i=0; i<mutations.length; ++i) {
for(var j=0; j<mutations[i].addedNodes.length; ++j) {
var addedNode = mutations[i].addedNodes[j];
//NOTE: if the element was added as child of another element, you would have to traverse
// the addedNode to find it. I recommend the jQuery solution above if that's the case
if(addedNode.tagName == "SPAN" && addedNode.classList.contains("sound")) {
play(addedNode.innerText);
}
}
}
});
obs.observe(document.getElementById('canvas'), {childList: true, subtree: true});
<div id="canvas"></div>
<button id="go">Add span to canvas</button>
You could probably try onload event
You need a listener to detect the DOM change, MutationObserver
// Select the node that will be observed for mutations
var targetNode = document.getElementById('some-id');
// Options for the observer (which mutations to observe)
var config = { attributes: true, childList: true };
// Callback function to execute when mutations are observed
var callback = function(mutationsList) {
for(var mutation of mutationsList) {
if (mutation.type == 'childList') {
console.log('A child node has been added or removed.');
}
else if (mutation.type == 'attributes') {
console.log('The ' + mutation.attributeName + ' attribute was modified.');
}
}
};
// Create an observer instance linked to the callback function
var observer = new MutationObserver(callback);
// Start observing the target node for configured mutations
observer.observe(targetNode, config);
// Later, you can stop observing
observer.disconnect();
I am trying to use mutationobserver for multiple nodes.
__w2_modal_wrapper_14
Have childnodes but 15,16,17 don't have any nodes. they will automatically load when scroll goes down. And I want a check on every nodes __w2_modal_wrapper_14, __w2_modal_wrapper_15, __w2_modal_wrapper_16 and __w2_modal_wrapper_17 and more as the web will load.
So please suggest any solution.
var MutationObserver = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver;
var list = document.getElementById('#__w2_modal_wrapper_14');
var observer = new MutationObserver(function(mutations) {
mutations.forEach(function(mutation) {
if (mutation.type === 'childList') {
alert("change");
}
});
});
observer.observe(list, {
attributes: true,
childList: true,
characterData: true
});
I would like to know about all changes in some DOM element on one site that is not mine so I could receive browser notifications about DOM element changes.
How could I do this if I can't write a code on the site?
I want to use this approach:
// select the target node
var target = document.getElementById('some-id');
// create an observer instance
var observer = new MutationObserver(function(mutations) {
mutations.forEach(function(mutation) {
console.log(mutation.type);
});
});
// configuration of the observer:
var config = { attributes: true, childList: true, characterData: true };
// pass in the target node, as well as the observer options
observer.observe(target, config);
// later, you can stop observing
observer.disconnect();
<div id="some-id"></div>
Thank you!
You can always add client side code to any website. That is the main behaviour of browser extensions for example.
But you can also just take your code and paste it to your browser's console (Chrome: Ctrl+Shift+J or F12)
In this example we will obeserve the <div id="question-header"> of this SO page.
// select the target node
var target = document.getElementById('question-header');
// create an observer instance
var observer = new MutationObserver(function(mutations) {
Notification.requestPermission(function (permission) {
if (permission === "granted") {
var notification = new Notification("Something has changed!");
}
});
mutations.forEach(function(mutation) {
console.log(mutation.type);
});
});
// configuration of the observer:
var config = { attributes: true, childList: true, characterData: true };
// pass in the target node, as well as the observer options
observer.observe(target, config);
Then execute this to test if it is working:
var node = document.createElement("b");
var textnode = document.createTextNode("Hello new item");
node.appendChild(textnode);
document.getElementById("question-header").appendChild(node);
You can achieve that with something like this :
$(function(){
var keep = '';
var ajaxurl = "http://foo.bar";
setInterval(function(){
$.get( ajaxurl, { sample_data : 'test' }, function(response){
var log = "<p>Checked</p>";
if( keep != '' && keep !== response )
log = "<p>Something has changed</p>";
$('.log-container').append( log );
});
}, 2000);
});
but you can do a more advanced thing with pusherJS https://github.com/pusher/pusher-js