49

HTML5 包含一个“突变观察者”的概念来监控浏览器 DOM 的变化。

您的观察者回调将传递看起来很像 DOM 树片段的数据。我不知道它们是否正是这样,或者它们是如何工作的。

但是,当您编写代码以与您无法控制的第 3 方站点交互时,例如使用 Greasemonkey 脚本或 Google Chrome 用户脚本,您必须检查传入的元素树以查找与您相关的信息。

这对于选择器来说要简单得多,就像使用任何 DOM 一样,比手动遍历树要简单得多,尤其是对于跨浏览器代码。

有没有办法将 jQuery 选择器与传递给 HTML5 突变观察者回调的数据一起使用?

4

4 回答 4

66

是的,您可以在返回到突变观察者回调的数据上使用 jQuery 选择器。

看到这个 jsFiddle。

假设你有这样的 HTML:

<span class="myclass">
    <span class="myclass2">My <span class="boldly">vastly</span> improved</span>
    text.
</span>


你设置了一个观察者,像这样:

var targetNodes         = $(".myclass");
var MutationObserver    = window.MutationObserver || window.WebKitMutationObserver;
var myObserver          = new MutationObserver (mutationHandler);
var obsConfig           = { childList: true, characterData: true, attributes: true, subtree: true };

//--- Add a target node to the observer. Can only add one node at a time.
targetNodes.each ( function () {
    myObserver.observe (this, obsConfig);
} );

function mutationHandler (mutationRecords) {
    console.info ("mutationHandler:");

    mutationRecords.forEach ( function (mutation) {
        console.log (mutation.type);

        if (typeof mutation.removedNodes == "object") {
            var jq = $(mutation.removedNodes);
            console.log (jq);
            console.log (jq.is("span.myclass2"));
            console.log (jq.find("span") );
        }
    } );
}

你会注意到我们可以在mutation.removedNodes.


如果您随后$(".myclass").html ("[censored!]");从控制台运行,您将从 Chrome 和 Firefox 获得此信息:

mutationHandler:
childList
jQuery(<TextNode textContent="\n ">, span.myclass2, <TextNode textContent="\n text.\n ">)
true
jQuery(span.boldly)

这表明您可以在返回的节点集上使用普通的 jQuery 选择方法。

于 2012-09-26T08:02:39.080 回答
7

我没有任何个人代码片段,但我有三个资源可能会有所帮助:

来自链接 #3 'jquery-mutation-summary' 库的示例:

// Use document to listen to all events on the page (you might want to be more specific)
var $observerSummaryRoot = $(document);

// Simplest callback, just logging to the console
function callback(summaries){
    console.log(summaries);
}

// Connect mutation-summary
$observerSummaryRoot.mutationSummary("connect", callback, [{ all: true }]);

// Do something to trigger mutationSummary
$("<a />", { href: "http://joelpurra.github.com/jquery-mutation-summary"}).text("Go to the jquery-mutation-summary website").appendTo("body");

// Disconnect when done listening
$observerSummaryRoot.mutationSummary("disconnect");
于 2012-09-26T07:11:56.207 回答
3

I was working on a very similar problem for a Stack Exchange script I'm working on, and I needed to be able to monitor the DOM for changes. The jQuery docs didn't have anything helpful, but I did discover that the DOMNodeInserted event works in Chrome:

document.addEventListener("DOMNodeInserted", function(event){
    var element = event.target;

    if (element.tagName == 'DIV') {
        if (element.id == 'seContainerInbox') {
            //alert($('#seContainerInbox').parent().get(0).tagName);
            trimStoredItems();
            $('#seTabInbox').click();
            //   var newCount = getNewCount();
            // if there are new inbox items, store them for later
            storeNewInboxItems();
            applyNewStyleToItems();
        }
    }
});

I'm not 100% sure if this works in Firefox as I haven't got that far yet in the development process. Hope this helps!

于 2012-09-26T07:07:05.540 回答
2

我知道这是一个老问题,但也许这可以帮助其他人寻找替代解决方案。我最近了解了 Mutation Observers 并想尝试将它们与 jQuery 一起使用。我想出了两种可能的方法并将它们变成插件。代码可在此处获得。

第一种方法 ( jquery.observeWithEvents.js) 使用 jQuery 的trigger()函数来触发可以通过 jQuery 的函数绑定到的事件insertNode或事件。第二种方法 ( ) 使用传统的回调参数。请查看自述文件以获取示例和用法。removeNodeon()jquery.observeWithCallbacks.js

于 2013-07-03T03:37:15.970 回答