J'essaie de désactiver une fonction lorsqu'une division particulière est créée. En termes simples, j'ai quelque chose comme ceci:
<a href="" id="foo">Click me!</a>
<script>
$("#foo").live("click",function(e) {
e.preventDefault();
$(this).append($("<div />").html("new div").attr("id","bar"));
});
</script>
Avant, j'avais des événements de mutation écouter la création de div # bar - quelque chose comme ça:
$("#bar").live("DOMNodeInserted", function(event) {
console.log("a new div has been appended to the page");
});
Existe-t-il un équivalent utilisant Mutation Observers? J'ai essayé attrchange.js présenté sur Pouvez-vous avoir un déclencheur de hook javascript après les changements d'objet de style d'un élément DOM? mais ce plugin détecte uniquement quand un élément a été modifié, pas quand il est créé.
Il s'agit d'un code qui écoute les mutations dans la liste d'enfants de #foo
Et vérifie si un enfant avec l'ID de bar
est ajouté.
MutationObserver = window.MutationObserver || window.WebKitMutationObserver;
$("#foo").live("click",function(e) {
e.preventDefault();
$(this).append($("<div />").html("new div").attr("id","bar"));
});
// define a new observer
var obs = new MutationObserver(function(mutations, observer) {
// look through all mutations that just occured
for(var i=0; i<mutations.length; ++i) {
// look through all added nodes of this mutation
for(var j=0; j<mutations[i].addedNodes.length; ++j) {
// was a child added with ID of 'bar'?
if(mutations[i].addedNodes[j].id == "bar") {
console.log("bar was added!");
}
}
}
});
// have the observer observe foo for changes in children
obs.observe($("#foo").get(0), {
childList: true
});
Cependant, cela n'observe que #foo
. Si vous souhaitez rechercher l'ajout de #bar
En tant que nouvel enfant d'autres nœuds, vous devez observer ces parents potentiels avec des appels supplémentaires à obs.observe()
. Pour observer un nœud avec l'ID de baz
, vous pouvez faire:
obs.observe($('#baz').get(0), {
childList: true,
subtree: true
});
L'ajout de l'option subtree
signifie que l'observateur cherchera l'ajout de #bar
En tant qu'enfant o un descendant plus profond (par exemple petit-enfant).
Lorsque vous utilisez jQuery, l'utilisation de MutationObserver s peut être simplifiée comme indiqué ci-dessous.
$("#btnAddDirectly").click(function () {
$("#canvas").append($('<span class="stuff">new child direct</span>'));
});
$("#btnAddAsChildOfATree").click(function () {
$("#canvas").append($('<div><div><span class="stuff">new child tree</span></div></div>'));
});
var obs = new MutationObserver(function(mutations, observer) {
// using jQuery to optimize code
$.each(mutations, function (i, mutation) {
var addedNodes = $(mutation.addedNodes);
var selector = "span.stuff"
var filteredEls = addedNodes.find(selector).addBack(selector); // finds either added alone or as tree
filteredEls.each(function () { // can use jQuery select to filter addedNodes
alert('Insertion detected: ' + $(this).text());
});
});
});
var canvasElement = $("#canvas")[0];
obs.observe(canvasElement, {childList: true, subtree: true});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="canvas">
Canvas
</div>
<button id="btnAddDirectly">Add span directly to canvas</button>
<button id="btnAddAsChildOfATree">Add span as child of a tree</button>
Il est toujours important de noter que le deuxième argument de .observe()
, MutationObserverInit
, est important:
Dans les options, utilisez childList: true
Si le span
ne sera ajouté qu'en tant qu'enfant direct. subTree: true
S'il peut être à n'importe quel niveau en dessous de #canvas
.
De la docs :
childList
: défini sur true
si les ajouts et les suppressions des éléments enfants du nœud cible (y compris les nœuds de texte) doivent être observés.subtree
: défini sur true
si des mutations vers la cible et les descendants de la cible doivent être observées.