Alfred Huang
Alfred Huang

Reputation: 18235

$.fn.submit() event don't trigger inside an <iframe>

Simply speaking, I have a form, and a field.

<!-- inner.html -->
<form id="inner_form">
    <input type="text" name="username" />
    <input type="submit" />
</form>

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script>
$(function() {
    $('#inner_form').submit(function() {
        alert('Inner submit is triggered!');
    });
});
</script>
The above code goes well: when I click the submit button, it triggers the submit event of #inner_form, and alerts the sentence: Inner submit is triggered!


My problem is, when I make another page, and loads the inner.html inside an <iframe>:

<!-- outer.html -->
<iframe id="the_frame" src="inner.html">
</iframe>
<button id="outer_submit">Submit Inner</button>

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script>
$(function() {
    $('#outer_submit').click(function() {
        // it don't trigger the inner submit() event!
        $('#the_frame').contents().find('#inner_form').submit();
    });
});
</script>
As the above code (which might not working well in the snnipet), I click the #outer_submit button, and the #inner_form do submitted, but the event I defined inside it don't triggered!


Why do this happen? And if I want the inner event triggered well with outer action, how can I got it?

Upvotes: 3

Views: 1723

Answers (1)

Stephan Muller
Stephan Muller

Reputation: 27620

While I can't give you an answer as to 'why', here's some discoveries I made while testing this:

Replacing the .submit() action with

$('#the_frame').contents().find('#inner_form input[type="submit"]').click();

Will trigger the alert. This isn't a proper fix though, because there's more ways to submit a form. Still, it shows that the events are not completely broken. So I dug deeper.


I tried using native javascript events instead of jquery's .submit([function]) bind in inner.html:

<form id="inner_form" onsubmit="alert('hi')">

That actually shows the alert. And so does this:

$('#inner_form')[0].onsubmit = function() {
    alert('Inner submit is triggered!');
}

So there seems to be something wrong with the way jQuery sets and/or detects its own submit() method.


One more try:

$('#inner_form').on('submit', function() {
    alert('Inner submit is triggered!');
});

This also shows the submit!

My wild guess is that for some reason when the events in inner.html are being bound, it doesn't know the form yet, even though the bind is wrapped in an implicit document.ready event through $(function(){ .. });.

As for the how and why of this I remain in the dark, but the fix is simple: wrap your event binds in an .on() method.

Upvotes: 2

Related Questions