javascript - Mutation Observer para crear nuevos elementos
jquery mutation-observers (2)
Estoy tratando de hacer que una función se active cuando se crea un div en particular. En el más simple de los términos, tengo algo como esto:
<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>
Antes, tuve eventos de mutación para escuchar la creación de div # bar, algo como esto:
$("#bar").live("DOMNodeInserted", function(event) {
console.log("a new div has been appended to the page");
});
¿Hay algún equivalente que use Mutation Observers? Intenté attrchange.js en ¿Puedes tener un activador de enganche de JavaScript después de que cambie el objeto de estilo de un elemento DOM? pero ese complemento solo detecta cuando un elemento ha sido modificado, no cuando se ha creado.
Cuando se utiliza jQuery, el uso de MutationObserver se puede simplificar como se muestra a continuación.
$("#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>
Siempre es importante tener en cuenta que el segundo argumento para .observe()
, MutationObserverInit
, es importante:
En las opciones, use childList: true
si el span
solo se agregará como un elemento secundario directo. subTree: true
si puede estar en cualquier nivel abajo #canvas
.
De los MutationObserver :
-
childList
: se establece entrue
si se deben observar las adiciones y eliminaciones de los elementos secundarios del nodo de destino (incluidos los nodos de texto). -
subtree
: se establece entrue
si se deben observar las mutaciones al objetivo y los descendientes del objetivo.
Este es un código que escucha las mutaciones en la lista de #foo
secundarios de #foo
y comprueba si se agrega un elemento secundario con la identificación de la bar
.
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
});
Sin embargo, esto solo observa #foo
. Si desea buscar la adición de #bar
como hijo nuevo de otros nodos, debe observar a los posibles padres con llamadas adicionales a obs.observe()
. Para observar un nodo con la identificación de baz
, puede hacer:
obs.observe($(''#baz'').get(0), {
childList: true,
subtree: true
});
La adición de la opción de subtree
significa que el observador buscará la adición de #bar
como descendiente o descendiente más profundo (por ejemplo, nieto).