用于创建新元素的Mutation Observer

Jim*_* Ha 32 javascript jquery dom4 mutation-observers

我正在尝试在创建特定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>
Run Code Online (Sandbox Code Playgroud)

以前,我有突变事件听取div#bar的创建 - 这样的事情:

$("#bar").live("DOMNodeInserted", function(event) {
    console.log("a new div has been appended to the page");
});
Run Code Online (Sandbox Code Playgroud)

是否有使用Mutation Observers的等价物?我尝试了attrchange.js功能你可以在DOM元素的样式对象更改后有一个javascript钩子触发器吗?但该插件仅检测元素何时被修改,而不是何时创建.

aps*_*ers 30

这是侦听子列表中的突变的代码,#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
});
Run Code Online (Sandbox Code Playgroud)

但是,这只能观察到#foo.如果您想要寻找#bar其他节点的新子节点,您需要通过额外的调用来观察这些潜在的父节点obs.observe().要观察id为的节点baz,您可以:

obs.observe($('#baz').get(0), {
  childList: true,
  subtree: true
});
Run Code Online (Sandbox Code Playgroud)

添加subtree选项意味着观察者将寻找添加#bar为子更深的后代(例如孙子).

  • @ŠimeVidas对不起,是的,我的错误; 我有供应商前缀,因为我在Chrome中测试.我现在已经规范化了供应商前缀,否则应该可以正常工作.它是Firefox中的"MutationObserver"和Webkit中的"WebKitMutationObserver",但它们的工作方式相同.**[小提琴演示](http://jsfiddle.net/5Sb4M/)**. (5认同)
  • @JimmyHa这将适用于Firefox和Webkit浏览器.Opera和IE还没有支持Mutation Observers,所以你需要使用像DOM3突变事件这样的后备选项(或者等待很长时间才能使DOM4方法达到实现成熟度). (3认同)
  • 仅适用于Chrome/Safari的解决方案几乎不是合法的解决方案. (2认同)

acd*_*ior 6

使用jQuery时,可以简化MutationObserver的用法,如下所示。

$("#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});
Run Code Online (Sandbox Code Playgroud)
<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>
Run Code Online (Sandbox Code Playgroud)

这是通知,第二个参数总是很重要的.observe()MutationObserverInit是很重要的:

在选项中,childList: true如果span将仅作为直接子项添加,请使用。subTree: true如果它可以在低于的任何水平#canvas

文档

  • childList:设置为true是否要观察和添加目标节点的子元素(包括文本节点)。
  • subtree:设置为true是否要观察到目标和目标后代的突变。