jQuery 选择器可以与 DOM 变异观察者一起使用吗?
Posted
技术标签:
【中文标题】jQuery 选择器可以与 DOM 变异观察者一起使用吗?【英文标题】:Can jQuery selectors be used with DOM mutation observers? 【发布时间】:2012-09-17 18:06:26 【问题描述】:html5 包含"mutation observers" 的概念,用于监控浏览器 DOM 的变化。
您的观察者回调将传递看起来很像 DOM 树 sn-ps 的数据。我不知道它们到底是不是这样,或者它们是如何工作的。
但是,当您编写代码以与您无法控制的第 3 方网站交互时,例如使用 Greasemonkey 脚本或 Google Chrome 用户脚本,您必须检查传入的元素树以查找哪些信息是相关的给你。
使用选择器比手动遍历树要简单得多,就像使用任何 DOM 一样,尤其是对于跨浏览器代码。
有没有办法将 jQuery 选择器与传递给 HTML5 突变观察者回调的数据一起使用?
【问题讨论】:
相关问题:Is there a jQuery DOM change listener?, DOM Mutation event in JQuery or vanilla javascript 参见:Can I use Jquery selectors on an HTML string that is not attached to the DOM? 有一个 插件:github.com/kapetan/jquery-observe 【参考方案1】:我知道这是一个老问题,但也许这可以帮助其他人寻找替代解决方案。我最近了解了 Mutation Observers 并想尝试将它们与 jQuery 一起使用。我想出了两种可能的方法并将它们变成插件。代码可用here。
第一种方法 (jquery.observeWithEvents.js
) 使用 jQuery 的 trigger()
函数来触发 insertNode
或 removeNode
事件,该事件可以通过 jQuery 的 on()
函数绑定到。第二种方法 (jquery.observeWithCallbacks.js
) 使用传统的回调参数。请查看自述文件以获取示例和用法。
【讨论】:
【参考方案2】:是的,您可以对返回到突变观察者回调的数据使用 jQuery 选择器。
See this 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
上使用jQuery。
如果您随后从控制台运行 $(".myclass").html ("[censored!]");
,您将从 Chrome 和 Firefox 获得此信息:
mutationHandler:
childList
jQuery(<TextNode textContent="\n ">, span.myclass2, <TextNode textContent="\n text.\n ">)
true
jQuery(span.boldly)
这表明您可以在返回的节点集上使用普通的 jQuery 选择方法。
【讨论】:
你知道它是否被 jQuery 官方支持,它是否适用于 jQuery 支持的所有浏览器以及哪些支持突变观察者?难道它只是碰巧在这些浏览器中工作?看起来可能是这种情况,因为行为似乎有所不同......无论如何我现在肯定会玩它! (-: 我认为这不是“官方”支持的问题。removedNodes
和 addedNodes
return lists of nodes 之类的东西。 jQuery 整天都在这样的列表上工作,一直如此。 ...该代码适用于 Firefox 和 Chrome,并且符合 W3C 规范。它应该适用于任何支持此类事件的浏览器。
当我问这个问题的时候,我的脑海里有一些模糊的回忆,关于“sn-ps”在过去没有附加到文档 DOM 时会有所不同,并且不确定在 jQuery 下是否仍然存在任何此类差异。
不幸的是,jsFiddle 不再工作了,至少在 FF 24.0 中。它会在控制台中发出一些警告并死掉。如果您无法复制问题,我可以列出错误。不过,它确实可以在 Chrome 30.0.something 中使用。
@Gutza,我刚刚在 FF 24 和 Chrome 最新版本中对其进行了测试。它仍然有效,我没有看到任何错误。从干净的 FF 配置文件或其他机器重试。【参考方案3】:
我没有任何个人代码 sn-ps,但我有三个资源可能会有所帮助:
Mutabor Github Repository Article + JQuery Utility for Mutators "jquery-mutation-summary" - extension of mutation-summary(可能是这三个中最好的)来自链接 #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");
【讨论】:
嗯,我只是尝试使用Mutation Summary 的非 jQuery 原始版本,但发现它不适用于没有考虑用户脚本设计的页面。它擅长观察id
或 class
引用的元素的更改,但当您关心的所有更改都是几个元素深度或生成的 id
s 和 className
s 时,它就不那么好了。
在我看来,jQuery 在这种情况下只是装点门面。我错过了什么吗?【参考方案4】:
我正在处理我正在处理的 Stack Exchange 脚本的一个非常相似的问题,我需要能够监视 DOM 的更改。 jQuery 文档没有任何帮助,但我确实发现 DOMNodeInserted 事件在 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();
);
我不能 100% 确定这是否适用于 Firefox,因为我在开发过程中还没有走那么远。希望这会有所帮助!
【讨论】:
我正在使用WebKitMutationObserver()
,我认为它是新的并受支持,旧的东西已被弃用。我不确定DOMNodeInserted
是否属于“旧东西”。 WebKitMutationObserver
传递给你一个突变对象,虽然我猜它本身不是 DOM 基本上是一个 DOM 引用包。我想知道我是否可以用 jQuery 包装它或其中的一些引用...
我自己没有使用过这个,但从你描述它的方式来看,我怀疑你可能不得不自己访问 RAW DOM 元素,这样你就可以将它们传递给一个 jQuery 对象,就像从两个谜题。我想这真的取决于实际的数据类型。也许看看“typeof”给你什么,看看它是否可以轻松包装。希望这会有所帮助!
DOMNodeInserted
不是突变观察者的一部分。它是突变观察者取代的旧的、有缺陷的、已弃用的突变事件系统!
@BrockAdams - 如果你有答案,你应该发布一个答案。实际上,一旦遇到它,我就打算用我自己的代码中更好的东西来替换它。以上是关于jQuery 选择器可以与 DOM 变异观察者一起使用吗?的主要内容,如果未能解决你的问题,请参考以下文章