using document.getElementsByTagName on a page with

2019-02-23 09:06发布

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.

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

2条回答
男人必须洒脱
2楼-- · 2019-02-23 09:12

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

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

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]);
}
查看更多
走好不送
3楼-- · 2019-02-23 09:32

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:

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

查看更多
登录 后发表回答