javascript 在带有 iFrame 的页面上使用 document.getElementsByTagName - iframe 内的元素没有被拾取

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/11144479/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-26 12:11:12  来源:igfitidea点击:

using document.getElementsByTagName on a page with iFrames - elements inside the iframe are not being picked up

javascriptiframegetelementsbytagname

提问by njj56

newer to javascript. On my page (asp.net application, vb as serverside language), I am using document.getElementsByTagName("img") to get all img tagged html items. I am noticing one in particular does not show up in this list (I was able to put them into an array and access the items individually - code below). This item is is contained inside an iframe (the iframe doesn't use SRC or anything else, just defined then the html inside it is right there in the source, doesnt load from another page - this is automatically generated by a crystal reports viewer generated at runtime, which is why I am unable to copy to show this). Is the getElementsByTagName not picking up this image because it is inside an iframe? I need to be able to access this img's src (the image is another auto generated item from the crystal report viewer). If the reason why this is not picked up is due to the iframe, is there any way to either run this on items inside the iframe? Or just get the "innerhtml" type property for everything inside the iframe so that the img src can be accessed. Thank you for your help.

较新的javascript。在我的页面(asp.net 应用程序,vb 作为服务器端语言),我使用 document.getElementsByTagName("img") 来获取所有 img 标记的 html 项目。我特别注意到一个没有出现在这个列表中(我能够将它们放入一个数组并单独访问这些项目 - 下面的代码)。该项目包含在 iframe 中(iframe 不使用 SRC 或其他任何东西,只是定义了它里面的 html 就在源中,不会从另一个页面加载 - 这是由水晶报告查看器自动生成的在运行时,这就是为什么我无法复制以显示这一点)。getElementsByTagName 是不是因为它在 iframe 内而没有拾取这个图像?我需要能够访问这个 img 的 src(图像是另一个从水晶报告查看器自动生成的项目)。如果没有被选中的原因是由于 iframe,有没有办法在 iframe 内的项目上运行它?或者只是获取 iframe 中所有内容的“innerhtml”类型属性,以便可以访问 img src。谢谢您的帮助。

var IMGmatches = [];
        var IMGelems = document.getElementsByTagName("img");
        for (var j = 0; j < IMGelems.length; j++) {
            IMGmatches.push(IMGelems[j]);
        }

回答by Niet the Dark Absol

That's because elements that are in iframes are not a part of the parent document.

这是因为 iframe 中的元素不是父文档的一部分。

To get anything inside an iframe, you need to access the iframe's contentDocument. So, your code might look like this:

要在 iframe 中获取任何内容,您需要访问 iframe 的contentDocument. 因此,您的代码可能如下所示:

var IMGmatches = [], IMGelems = document.getElementsByTagName("img"),
    iframes = document.getElementsByTagName('iframe'), l = IMGelems.length,
    m = iframes.length, i, j;
for( i=0; i<l; i++) IMGmatches[i] = IMGelems[i];
for( j=0; j<m; j++) {
    IMGelems = iframes[j].contentDocument.getElementsByTagName("img");
    l = IMGelems.length;
    for( i=0; i<l; i++) IMGmatches.push(IMGelems[i]);
}

回答by kofifus

Here is a function that will return a set of all elements starting from(and including) a root, including iframes where possible (non CORS) and shadow dom:

这是一个函数,它将返回一组从(并包括)根开始的所有元素,包括可能的 iframe(非 CORS)和 shadow dom:

const subtreeSet = (root, theset) => {
 if (!theset) theset=new Set();
 if (!root || theset.has(root)) return theset;
 theset.add(root);
 if (root.shadowRoot) {
  Array.from(root.shadowRoot.children).forEach(child => subtreeSet(child, theset));
 } else {
  if (root.tagName === 'IFRAME') { try { root=root.contentDocument.body; theset.add(root); } catch (err) { root=null; /* CORS */ } }
   if (root && root.getElementsByTagName) for (const child of root.getElementsByTagName('*')) subtreeSet(child, theset);
 }
 return theset;
}

subtreeSet(document).forEach(elem => { 
  if (elem.style) elem.style.backgroundColor='yellow'; 
});
<div>TOP</div><br>
<div>IFRAME<br><iframe></iframe></div>

Tested only in Chrome

仅在 Chrome 中测试