Tengo un archivo HTML principal que contiene varios iframes alojados en el mismo dominio. Ahora me gustaría recorrer todos los iframes y cambiar su apariencia visual agregando estilos CSS con javascript simple para ellos:
<!DOCTYPE html> <html> <head> <title> Altering CSS in iframe </title> </head> <body> <h1>Parent HTML</h1> <iframe id="frameID1" name="frameID1" srcdoc=" <!DOCTYPE html> <html> <head> <meta charset="utf-8"> </head> <body> <p>This is my iframe #1</p> </body> </html> "></iframe> <iframe id="frameID2" name="frameID2" srcdoc=" <!DOCTYPE html> <html> <head> <meta charset="utf-8"> </head> <body> <p>This is my iframe #2</p> </body> </html> "></iframe> <iframe id="frameID3" name="frameID3" srcdoc=" <!DOCTYPE html> <html> <head> <meta charset="utf-8"> </head> <body> <p>This is my iframe #3</p> </body> </html> "></iframe> <script> var iframes = document.getElementsByTagName("iframe"); for (var i = 0; i < iframes.length; i++) { iframes.item(i).addEventListener("load", function() { var node = document.createElement('style'); node.appendChild(document.createTextNode('body { background: red; }')); window.frames[i].document.head.appendChild(node) }) } </script> </body> </html> Pero el bucle en el código javascript no funciona. Configuré un violín, donde cambié window.frames[i].document.head.appendChild(node) a window.frames[i-2].document.head.appendChild(node) que muestra un efecto, pero solo cambia el estilo en UN iframe en lugar de en todos los iframes: https://jsfiddle.net/5a8bdynm/
¿Qué tengo que modificar para efectuar todos los iframes?
Está utilizando var para definir su índice i en el bucle for . Entonces, su índice es una variable global.
Pero su evento (carga) es asíncrono (1), por lo que cuando se carga el primer iframe, el índice ya tiene el valor de 3. En este caso, window.frames[i] SIEMPRE se referirá a window.frames[3] que ni siquiera existe.
Si reemplaza var con let , cada ciclo de ciclo recibirá su propio valor de índice por separado y window.frames[i] se referirá al iframe adecuado.
const iframes = document.getElementsByTagName("iframe") for (let i = 0; i < iframes.length; i++) { // your code} En general, debe EVITAR usar var . Prefiere let y const como mejor práctica.
(1) EDITAR: Por cierto, la naturaleza asíncrona del evento de carga no es tan relevante en este caso ya que el código es parte de un controlador de eventos; entonces, no importa cuál sea el evento, se ejecutará de todos modos DESPUÉS de que finalice el ciclo (y luego, después de que la variable de índice global obtenga el valor de 3)