我正在尝试在创建特定div时使函数关闭。用最简单的术语来说,我有这样的事情:
<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>
以前,我有突变事件听取div#bar的创建 - 这样的事情:
$("#bar").live("DOMNodeInserted", function(event) {
console.log("a new div has been appended to the page");
});
是否有使用Mutation Observers的等价物?我尝试了在Can you have a javascript hook trigger after a DOM element's style object changes?上的attrchange.js,但该插件只检测元素何时被修改,而不是在创建时。
这是监听#foo
子列表中的突变的代码,并检查是否添加了id为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
});
但是,这只能观察#foo
。如果你想寻找添加#bar
作为其他节点的新子节点,你需要通过额外调用obs.observe()
观察那些潜在的父母。要观察id为baz
的节点,您可以执行以下操作:
obs.observe($('#baz').get(0), {
childList: true,
subtree: true
});
添加subtree
选项意味着观察者将寻找添加#bar
作为儿童或更深层次的后代(例如孙子)。
使用jQuery时,可以简化MutationObservers的使用,如下所示。
$("#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>
值得注意的是,.observe()
,MutationObserverInit
的第二个论点很重要:
在选项中,如果childList: true
仅作为直接子项添加,请使用span
。 subTree: true
,如果它可以在低于#canvas
的任何水平。
来自docs:
childList
:如果要观察目标节点的子元素(包括文本节点)的添加和删除,则设置为true
。subtree
:如果要观察到目标和目标后代的突变,请设置为true
。