Iframe onload event only after an anchor onclick

Sample code:

<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
<iframe name="iframe_a" onload="alert('Thanks for the visit!');"></iframe>
<a href="http://www.example.com/" target="iframe_a">Go!</a>
</body>
</html>

I’d like to see the alert message after clicking on the link and when the iframe finishes loading. But now it appears on the initial page load, too. How can I achieve it?

The following script should do the job.


function done() {
    //some code after iframe has been loaded
}

function WaitForIFrame() {
    if (iframe.readyState !== "complete") {
        setTimeout(WaitForIFrame, 200);
    } else {
        done();
    }
}

var iframe = document.getElementById('iframe_a');
WaitForIFrame();

Dear Paul,

Is this what you mean?

<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
<iframe name="iframe_a" onload="alert('Thanks for the visit!');"></iframe>
<a href="http://www.example.com/" target="iframe_a">Go!</a>
<script>
function done() {
    //some code after iframe has been loaded
}
 
function WaitForIFrame() {
    if (iframe.readyState !== "complete") {
        setTimeout(WaitForIFrame, 200);
    } else {
        done();
    }
}
 
var iframe = document.getElementById('iframe_a');
WaitForIFrame();
</script>
</body>
</html>

If so, it doesn’t work.

There are certain parts that I have left for you to complete.

Here’s the best I can come up with:

<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
<iframe name="iframe_a"></iframe>
<a href="http://www.example.com/" target="iframe_a">Go!</a>
<script>
function done() {
    alert('Thanks for the visit!');
}
 
function WaitForIFrame() {
    if (iframe.readyState !== "complete") {
        setTimeout(WaitForIFrame, 200);
    } else {
        done();
    }
}
 
var iframe = document.getElementById('iframe_a');
WaitForIFrame();
</script>
</body>
</html>

But still to no luck!

What is being assigned to the iframe variable?

The function WaitForIFrame();?

P.S. Sorry if I’m a zero beginner in JavaScript! :frowning:

No, that function is being called on the line immediately after.

You have to learn these things at some stage. If there’s anything that you want to know more about, we’ll be happy to oblige.

Now, what is being assigned to the iframe variable?

document.getElementById(‘iframe_a’);?

Good - so in your HTML code, use an id attribute to identify that frame element. Not a name attribute.

The name attribute should only be used for form elements these days.

Done:

<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
<iframe id="iframe_a" name="iframe_a"></iframe>
<a href="http://www.example.com/" target="iframe_a">Go!</a>
<script>
function done() {
    alert('Thanks for the visit!');
}
 
function WaitForIFrame() {
    if (iframe.readyState !== "complete") {
        setTimeout(WaitForIFrame, 200);
    } else {
        done();
    }
}
 
var iframe = document.getElementById('iframe_a');
WaitForIFrame();
</script>
</body>
</html>

What’s next?

You want the WaitForIFrame() command to be issued only after clicking on the link. So, give that link a suitable id, and move the WaitForIFrame() command inside of an onclick event for the link, such as this:


var link = document.getElementById('...');
link.onclick = function () {
    WaitForIFrame();
};

Hi there Rain Lover,

here is my little attempt at solving your problem…

[color=navy]<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
   "http://www.w3.org/TR/html4/strict.dtd">
<html lang="en">
<head>

<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="language" content="english">
<meta http-equiv="Content-Style-Type" content="text/css">
<meta http-equiv="Content-Script-Type" content="text/javascript">

<title>Go Go Go</title>

<style type="text/css">
body {
    background-color:#f0f0f0;
 }
#iframe_a_container {
    width:800px;
    height:400px;
    border:1px solid #999;
    margin:0 auto 20px;
    background-color:#fff;
    box-shadow:10px 10px 10px #666;
 }
#iframe_a {
    display:block;
    width:100%;
    height:100%;
    border:0;
 }
#go {
    display:block;
    width:50px;
    line-height:30px;
    border:1px solid #999;
    border-radius:5px;
    margin:auto;
    background-color:#fff;
    color:#333;
    text-align:center;
    text-decoration:none;
    box-shadow:0 0 10px #666;
 }
</style>

<script type="text/javascript">

function init(){
document.getElementById('go').onclick=function(){
   ifr=document.createElement('iframe');
   ifr.setAttribute('src',this.href);
   ifr.setAttribute('id','iframe_a');

ifr.onload=function() {
   alert('Thanks for the visit!');
 }
   document.getElementById('iframe_a_container').appendChild(ifr);
   return false;
  }
 }

   window.addEventListener?
   window.addEventListener('load',init,false):
   window.attachEvent('onload',init);

</script>

</head>
<body>

<div id="iframe_a_container"></div>

<div>
 <a id="go" href="http://www.bbc.co.uk/">Go!</a>
</div>

</body>
</html>
[/color]

Of course, my CSS will be better than my javascript. :smiley:

coothead

Hi there Rain Lover,

this amended code addresses the IE8 problem that you mentioned…

[color=navy]<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
   "http://www.w3.org/TR/html4/strict.dtd">
<html lang="en">
<head>

<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="language" content="english">
<meta http-equiv="Content-Style-Type" content="text/css">
<meta http-equiv="Content-Script-Type" content="text/javascript">

<title>Go Go Go</title>

<style type="text/css">
body {
    background-color:#f0f0f0;
 }
#iframe_a_container {
    width:800px;
    height:400px;
    border:1px solid #999;
    margin:0 auto 20px;
    background-color:#fff;
    box-shadow:10px 10px 10px #666;
 }
#iframe_a {
    display:block;
    width:100%;
    height:100%;
    border:0;
 }
#go {
    display:block;
    width:50px;
    line-height:30px;
    border:1px solid #999;
    border-radius:5px;
    margin:auto;
    background-color:#fff;
    color:#333;
    text-align:center;
    text-decoration:none;
    box-shadow:0 0 10px #666;
 }
</style>

<script type="text/javascript">

function init(){

   test=true;

document.getElementById('go').onclick=function(){
   ifr=document.createElement('iframe');
   ifr.setAttribute('src',this.href);
   ifr.src=this.href;
   ifr.setAttribute('id','iframe_a');

if(test==true){

ifr.onload=function() {
   alert('Thanks for the visit!');
 }
ifr.onreadystatechange=function(){
if(this.readyState=='complete'){
   alert('Thanks for the visit!');
  }
 }
   document.getElementById('iframe_a_container').appendChild(ifr);
   test=false;
  }
   return false;
  }
 }

   window.addEventListener?
   window.addEventListener('load',init,false):
   window.attachEvent('onload',init);

</script>

</head>
<body>

<div id="iframe_a_container"></div>

<div>
 <a id="go" href="http://www.bbc.co.uk/iplayer/">Go!</a>
</div>

</body>
</html>
[/color]

coothead

Thank you so much for your time and walking me through the steps above.
I finally came up with something simpler and would be happy to get your review:

<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
<iframe id="iframe_a" name="iframe_a" onload="if(this.className=='active'){alert('Thanks for the visit!');};"></iframe>
<a href="http://www.example.com/" target="iframe_a" onclick="document.getElementById('iframe_a').className='active';">Go!</a>
</body>
</html>

Yes that also works, but you don’t want to have scripting code embedded within your HTML code. You don’t embed CSS styles within your HTML code too do you?

Let’s remove that embedded scripting.


<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
<iframe id="iframe_a" name="iframe_a"></iframe>
<a id="link_a" href="http://www.example.com/" target="iframe_a">Go!</a>
<script src="iframeloaded.js"></script>
</body>
</html>


function waitForIFrame() {
    if (this.className === 'active') {
        alert('Thanks for the visit!');
    }
};

function initIFrameWait() {
    document.getElementById('iframe_a').className = 'active';
};

document.getElementById('iframe_a').onload = waitForIFrame;
document.getElementById('link_a').onclick = initIFrameWait;

The next issue is about why a class name is being used. If it’s not going to be used to affect any CSS styling of the iframe element, then you really should not allow the potential for unintended side-effects later on. Just Move the onload event assignment inside of the onclick event, so that you don’t need to mess around with class-based state-checking systems.


function waitForIFrame() {
    alert('Thanks for the visit!');
};

function initIFrameWait() {
    document.getElementById('iframe_a').onload = waitForIFrame;
};

document.getElementById('link_a').onclick = initIFrameWait;

That there is keeping it simple.

OK. How about this one:

<!DOCTYPE html>
<html>
    
    <head>
        <title></title>
        <script>
            var clicked = false;

            function activate() {
                clicked = true;
            }

            function pop() {
                if (clicked) {
                    alert('Thanks for the visit!');
                };
            }
        </script>
    </head>
    
    <body>
        <iframe name="iframe_a" onload="pop();"></iframe>
        <a href="http://www.example.com/" target="iframe_a" onclick="activate();">Go!</a>

    </body>

</html>

Just Move the onload event assignment inside of the onclick event, so that you don’t need to mess around with class-based state-checking systems.


function waitForIFrame() {
    alert('Thanks for the visit!');
};

function initIFrameWait() {
    document.getElementById('iframe_a').onload = waitForIFrame;
};

document.getElementById('link_a').onclick = initIFrameWait;

It makes sense and was the first thing I tried, but it doesn’t work in IE8.