bana
bana

Reputation: 397

Iframe load callback is called multiple times

I Have a simple web page and I have a following script.

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
    <script>
      function sendTraffic(typeOfTraffic){
        var ipAddr = document.getElementById("serverIpaddr").value;
        //alert(ipAddr);
        $("#WAFTest").attr("src", '/cgi-bin/test.py?wat='+typeOfTraffic+'&ipaddr='+ipAddr);
        $("#WAFTest").load(function () {
            alert("Test done");
        });
    }
    </script>

I have a button and this function sendTraffic is called. What I am seeing is Test done alert comes up once for the first time , twice for the second time and thrice for the third time and it keeps going on.

<button type="button" id="btnSendPing" class="btn btn-primary btn-lg" onclick="sendTraffic('sendping')">Send Ping Traffic</button>

I am not able to figure out what wrong I am doing. I am using twitter bootstrap just FYI.

EDIT: I am using chrome on Mac. #WAFTest is an Iframe. I am just trying to get data from the server and load it to the Iframe.

Upvotes: 5

Views: 7318

Answers (3)

Artur Filipiak
Artur Filipiak

Reputation: 9157

Like the others said, your .load() event should have been registered only once.

If solution posted in other answers doesn't work for you (although it should), there's another way to go

.one() :

Attach a handler to an event for the elements. The handler is executed at most once per element per event type

function sendTraffic(typeOfTraffic){
    var ipAddr = document.getElementById("serverIpaddr").value;
    //alert(ipAddr);
    $("#WAFTest").attr("src", '/cgi-bin/test.py?wat='+typeOfTraffic+'&ipaddr='+ipAddr);
    $("#WAFTest").one('load', function () {
        alert("Test done");
    });
}

DEMO


Althought solution posted in other answers is more proper. I would however remove onclick attribute and set click event handler for the element using jQuery.

To avoid ambiguities (as .load() is also a method used for AJAX request), I'd recommend use .on() to bind the load event handler

<iframe id="WAFTest"></iframe>
<button type="button" data-ping="sendping" class="btnSendPing btn btn-primary btn-lg">Send Ping Traffic</button>
<input id="serverIpaddr" value="something" />


$(document).ready(function(){

    $('.btnSendPing').click(function(){
        var ipAddr = $("#serverIpaddr").val();
        var typeOfTraffic = $(this).data('ping');
        $("#WAFTest").attr("src", '/cgi-bin/test.py?wat='+typeOfTraffic+'&ipaddr='+ipAddr);
    });

    $("#WAFTest").on('load', function () {
        alert("Test done");
    });

});

DEMO

Upvotes: 2

Torben H.
Torben H.

Reputation: 160

With every call of

$("#WAFTest").load(function () {
    alert("Test done");
});

you are binding a new Event-Listener to the load event of the iframe.

You have to put the call outside of the function, so it is only called and binded once.

Edit:

To prevent a failure of the code, when the DOM is not ready when the code-snippet is called, you have to wrap it in the ready function of jQuery

$(document).ready(function(){
    $("#WAFTest").load(function () {
        alert("Test done");
    });
})

Upvotes: 0

instanceofnull
instanceofnull

Reputation: 1081

Everytime you call sendTraffic() you bind a new instance of the event handler, which explains the behavior you describe: the first time you call it you attach a load event handler, then the iframe loads and the event fires. The second time you call the function, you bind another copy of the event handler to the load event, so both handlers execute the next time the iframe loads.

The solution is pretty simple: just take the event binding outside sendTraffic():

<script>
  function sendTraffic(typeOfTraffic) {
    var ipAddr = document.getElementById("serverIpaddr").value;
    //alert(ipAddr);
    $("#WAFTest").attr("src", '/cgi-bin/test.py?wat='+typeOfTraffic+'&ipaddr='+ipAddr);
  }
  $("#WAFTest").load(function() {
    alert("Test done");
  });
</script>

Hope this helps!

Upvotes: 0

Related Questions