Pregunta sobre getelementsbytagname, iframe, javascript – utilizando document.getElementsByTagName en una página con iFrames: los elementos dentro del iframe no se seleccionan

4

más nuevo a javascript. En mi página (aplicación asp.net, vb como idioma del servidor), estoy usando document.getElementsByTagName ("img") para obtener todos los elementos html etiquetados con img. Estoy notando que uno en particular no aparece en esta lista (pude colocarlos en una matriz y acceder a los elementos individualmente, código a continuación). Este elemento está contenido dentro de un iframe (el iframe no usa SRC o cualquier otra cosa, simplemente se define, entonces el html dentro está justo allí en la fuente, no se carga desde otra página; esto es generado automáticamente por un visor de informes Crystal generado en tiempo de ejecución, por lo que no puedo copiar para mostrar esto). ¿GetElementsByTagName no recoge esta imagen porque está dentro de un iframe? Necesito poder acceder a la fuente de este img (la imagen es otro elemento generado automáticamente desde el visor de informes de Crystal). Si la razón por la que esto no se ha detectado se debe al iframe, ¿hay alguna manera de ejecutar esto en los elementos dentro del iframe? O simplemente obtenga la propiedad de tipo "innerhtml" para todo lo que esté dentro del iframe para que se pueda acceder al img src. Gracias por tu ayuda.

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

Tu respuesta

2   la respuesta
0

Aquí hay una función que devolverá un conjunto de todos los elementos a partir de (e incluyendo) una raíz, incluyendo iframes donde sea posible (no CORS) y dom de la sombra:

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>

Probado solo en cromo

6

Esto se debe a que los elementos que están en iframes no son parte del documento principal.

Para obtener algo dentro de un iframe, necesita acceder al iframe.contentDocument. Por lo tanto, su código podría verse así:

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]);
}

Preguntas relacionadas