Home > Enterprise >  Looping through all iframes with plain javascript and altering their CSS styles
Looping through all iframes with plain javascript and altering their CSS styles

Time:02-28

I've got a parent HTML file that contains multiple iframes that are hosted at the same domain. Now I would like to loop though all iframes and change their visual appearing by adding CSS styles with plain javascript to them:

<!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=&quot;utf-8&quot;>
            </head>
            <body>
                <p>This is my iframe #1</p>
            </body>
        </html>
        "></iframe>

        <iframe id="frameID2" name="frameID2" srcdoc="
        <!DOCTYPE html>
        <html>
            <head>
                <meta charset=&quot;utf-8&quot;>
            </head>
            <body>
                <p>This is my iframe #2</p>
            </body>
        </html>
        "></iframe>

        <iframe id="frameID3" name="frameID3" srcdoc="
        <!DOCTYPE html>
        <html>
            <head>
                <meta charset=&quot;utf-8&quot;>
            </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>

But the loop in the javascript code doesn't work. I've set up a fiddle, where I changed window.frames[i].document.head.appendChild(node) to window.frames[i-2].document.head.appendChild(node) which shows an effect, but only changes the style in ONE iframe instead in all iframes: https://jsfiddle.net/5a8bdynm/

What di I have to alter in order to effect all iframes?

CodePudding user response:

You're using var to define your index i in the for loop. So, your index is a global variable.

But your event (load) is asynchronous (1), so when the first iframe loads, the index has already the value of 3. In this case, window.frames[i] will ALWAYS refer to the window.frames[3] that doesn't even exist.

If you replace var with let, each loop cycle will receive its own separate index value and window.frames[i] will refer to the proper iframe.

const iframes = document.getElementsByTagName("iframe")
for (let i = 0; i < iframes.length; i  ) { // your code}

In general, you should AVOID using var. Prefer let and const as a best practice.

(1) EDIT: BTW, the asyncronous nature of the load event isn't that relevant in this case as the code is part of an event handler; so, no matter what the event is, it will be anyway executed AFTER the loop ends (and then, after the global index variable got the value of 3)

  • Related