MutationObserver - 如何在 iframe 内检测 DOM 更改

15

首先让我解释一下这个问题:我的脚本有一个mutationobserver,可以检测到添加的节点,并对内容进行处理 - 例如比较和突出显示某些值。 当前的实现检测整个文档正文中的更改,目标如下:

var target = document.querySelector('body');

一切都很顺利,除了有iframe的情况。某些客户端页面有一个或多个iframe,而另一些则没有。

我的脚本添加在父文档的脚本标签中。

问题: a)是否可能使用相同的MutationObserver来检测body和iframe中的更改?即包括iframe在内的dom树中的所有内容。 b)如果单个观察者无法实现,那么备选方法是什么?

请注意:我的脚本只能进入主/父文档。


如果您不拥有iframe的域名,或者iframe没有向您提供访问其dom(document.domain = '...')的权限,则您无法进行操作。 - Get Off My Lawn
如果 iframe 的域与客户端的域相同,会怎样? - maX
只要正确获取 iframe,它就应该能够正常工作... document.getElementByTagName('iframe').document.body - Get Off My Lawn
你能具体一点吗?你的意思是我应该有第二个MutationObserver,以document.getElementByTagName('iframe').document.body作为目标吗? - maX
1个回答

17

如果您想监视每个iframe,您需要为每个iframe使用不同的mutationobserver。因此,如果您想在当前文档中使用一个,请确保您在那里有一个不同的observer。

如果您可以访问iframe,则可以按以下方式进行监视:

// Get the iframe body
let iframe = document.getElementById('my-iframe').document.body
// Setup the config
let config = { attributes: true, childList: true }
// Create a callback
let callback = function(mutationsList) { /* callback actions */ }

// Watch the iframe for changes
let observer = new MutationObserver(callback)
observer.observe(iframe, config)

如果iframe位于父域的子域上,您可以在iframe中使用以下内容:

// where parent.com is the parent domain of the iframe
document.domain = 'parent.com'

注意: document.domain现已被弃用。

如果您不拥有iframe的域名,那就没办法了。


我正在尝试这个。然而,iframe文档对象为空。 iframe的“baseURI”属性显示与父级相同的域。可能出了什么问题? - maX
确保在 iframe 和父窗口中 document.domain 相同。这是需要验证相同的属性。 - Get Off My Lawn
14
直到我将 iframe 更改为 document.getElementById('my-iframe').contentWindow.document.body 并在 config 变量中添加 subtree:true,才使其对我起作用/更加可靠。 - Toastrackenigma
请注意,如果您增加正文的大小,则此方法有效,但是如果您减小正文的大小(至少在Chrome中),则该方法无效 - 正文将保持最大高度。一个好的解决方案是在内容周围使用包装器,然后使用 getBoundingClientRect().height 获取包装器的高度。 - Toastrackenigma

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接