Fle*_*ore 382 javascript jquery google-chrome-extension
基本上我想在DIV的内容发生变化时执行脚本.由于脚本是独立的(chrome扩展和网页脚本中的内容脚本),我需要一种方法来简单地观察DOM状态的变化.我可以设置投票,但这似乎很草率.
aps*_*ers 460
几年后,现在正式有一个更好的解决方案. DOM4 Mutation Observers是弃用的DOM3突变事件的替代品.它们目前在现代浏览器中实现MutationObserver
(或者WebKitMutationObserver
在旧版Chrome中以供应商为前缀):
MutationObserver = window.MutationObserver || window.WebKitMutationObserver;
var observer = new MutationObserver(function(mutations, observer) {
// fired when a mutation occurs
console.log(mutations, observer);
// ...
});
// define what element should be observed by the observer
// and what types of mutations trigger the callback
observer.observe(document, {
subtree: true,
attributes: true
//...
});
Run Code Online (Sandbox Code Playgroud)
此示例侦听DOM更改document
及其整个子树,并将触发对元素属性的更改以及结构更改.草案规范有完整的有效突变监听器属性列表:
的childList
- 设定为
true
是否要观察目标儿童的突变.属性
- 设置为
true
是否要观察到目标属性的突变.characterData
- 设置为
true
是否要观察到目标数据的突变.子树
- 设定为
true
不仅仅是目标的突变,还要观察目标的后代.attributeOldValue
- 在需要记录突变之前,将
true
ifattributes
设置为true并设置target的属性值.characterDataOldValue
- 在需要记录突变之前,将
true
ifcharacterData
设置为true并设置目标数据.attributeFilter
- 如果不需要观察所有属性突变,则设置为属性本地名称列表(不包含名称空间).
(此列表是截至2014年4月的最新列表;您可以检查规范是否有任何更改.)
Anu*_*rag 205
编辑
这个答案现已弃用.看看apsillers的回答.
由于这是针对Chrome扩展程序的,因此您也可以使用标准DOM事件 - DOMSubtreeModified
.查看跨浏览器对此事件的支持.自1.0以来,Chrome一直受到支持.
$("#someDiv").bind("DOMSubtreeModified", function() {
alert("tree changed");
});
Run Code Online (Sandbox Code Playgroud)
在这里查看一个工作示例.
wOx*_*xOm 43
许多网站使用AJAX动态添加/显示/更改内容.有时使用它而不是现场导航,因此在这种情况下,以编程方式更改当前URL并且浏览器不会自动执行内容脚本,因为页面不是完全从远程服务器获取的.
MutationObserver(docs)从字面上检测DOM变化:
通过发送DOM事件来指示内容更改的站点的事件侦听器:
pjax:end
在document
被许多基于pjax的网站如GitHub上,message
上window
使用的Chrome浏览器如谷歌搜索,spfdone
在document
Youtube 上使用,通过setInterval定期检查DOM:
显然这只适用于等待由其id/selector标识的特定元素出现的情况,除非你发明某种指纹,否则它不会让你普遍检测新的动态添加内容现有的内容.
document.head.appendChild(document.createElement('script')).text = '(' +
function() {
// injected DOM script is not a content script anymore,
// it can modify objects and functions of the page
var _pushState = history.pushState;
history.pushState = function(state, title, url) {
_pushState.call(this, state, title, url);
window.dispatchEvent(new CustomEvent('state-changed', {detail: state}));
};
// repeat the above for replaceState too
} + ')(); this.remove();'; // remove the DOM script element
// And here content script listens to our DOM script custom events
window.addEventListener('state-changed', function(e) {
console.log('History state changed', e.detail, location.hash);
doSomething();
});
Run Code Online (Sandbox Code Playgroud)收听hashchange,popstate事件:
window.addEventListener('hashchange', function(e) {
console.log('URL hash changed', e);
doSomething();
});
window.addEventListener('popstate', function(e) {
console.log('State changed', e);
doSomething();
});
Run Code Online (Sandbox Code Playgroud)
有一些高级API可以使用导航:webNavigation,webRequest,但我们将使用简单的chrome.tabs.onUpdated事件监听器向内容脚本发送消息:
background.js
var rxLookfor = /^https?:\/\/(www\.)?google\.(com|\w\w(\.\w\w)?)\/.*?[?#&]q=/;
chrome.tabs.onUpdated.addListener(function(tabId, changeInfo, tab) {
if (rxLookfor.test(changeInfo.url)) {
chrome.tabs.sendMessage(tabId, 'url-update');
}
});
Run Code Online (Sandbox Code Playgroud)content.js
chrome.runtime.onMessage.addListener(function(msg, sender, sendResponse) {
if (msg === 'url-update') {
doSomething();
}
});
Run Code Online (Sandbox Code Playgroud)Zac*_*den 29
另一种方法取决于你如何改变div.如果您使用JQuery通过其html()方法更改div的内容,则可以扩展该方法并在每次将html放入div时调用注册函数.
(function( $, oldHtmlMethod ){
// Override the core html method in the jQuery object.
$.fn.html = function(){
// Execute the original HTML method using the
// augmented arguments collection.
var results = oldHtmlMethod.apply( this, arguments );
com.invisibility.elements.findAndRegisterElements(this);
return results;
};
})( jQuery, jQuery.fn.html );
Run Code Online (Sandbox Code Playgroud)
我们只是拦截对html()的调用,用这个调用一个注册函数,它在上下文中指的是获取新内容的目标元素,然后我们将调用传递给原始的jquery.html()函数.记得返回原始html()方法的结果,因为JQuery期望它用于方法链接.
有关方法覆盖和扩展的更多信息,请查看http://www.bennadel.com/blog/2009-Using-Self-Executing-Function-Arguments-To-Override-Core-jQuery-Methods.htm,这是哪里我完成了关闭功能.另请查看JQuery网站上的插件教程.
除了MutationObserver
API提供的“原始”工具外,还存在用于处理DOM突变的“便捷”库。
考虑:MutationObserver用子树表示每个DOM更改。因此,例如,如果您正在等待插入某个元素,则该元素可能位于的子元素中mutations.mutation[i].addedNodes[j]
。
另一个问题是,当您自己的代码因应突变而更改DOM时-您通常希望将其过滤掉。
一个解决此类问题的便捷库mutation-summary
(免责声明:我不是作者,只是一个满意的用户),它使您可以指定对自己感兴趣的内容的查询,并准确地获得该内容。
文档中的基本用法示例:
var observer = new MutationSummary({
callback: updateWidgets,
queries: [{
element: '[data-widget]'
}]
});
function updateWidgets(summaries) {
var widgetSummary = summaries[0];
widgetSummary.added.forEach(buildNewWidget);
widgetSummary.removed.forEach(cleanupExistingWidget);
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
262613 次 |
最近记录: |