Search code examples
javascriptjqueryiframejquery-tabs

javascript only works once when needed twice on page


I'm using a piece of JS twice for two, different yet the same, events.

To make it more simple, let's say I've got:

<script type="text/javascript">
    $(function(){
        $(".iframe").load(function(){
               $(this).contents().find("form").delegate(".clickThisCheckBox","click",function(){
                alert(this)
            })
        })
    })
</script>

<div class="tabs">
    <ul class="tabs-nav">
        <li><a href="#products">Products</a></li>
        <li><a href="#accessories">Accessories</a></li>
    </ul>
</div>

<div class="content">
    <div id="products">
        <iframe class="iframe">
            <form action="?" method="post">
                <input type="checkbox" name="checkBox1" class="clickThisCheckBox" />
            </form>
        </iframe>
    </div>

    <div id="accessories">
        <iframe class="iframe">
            <form action="?" method="post">
                <input type="checkbox" name="checkBox2" class="clickThisCheckBox" />
            </form>
        </iframe>       
    </div>
</div>

This a more simplified version than what I've got, but exactly the same concept.

So when the page loads, you click the checkbox in the open tab, and you'll successfully get the alert box with the object. When you click the next tab and try to click the checkbox, nothing happens.

There is no AJAX or separate loading going on. Everything gets rendered on the initial page load. Both iframes are loaded at the same time and you access a different once by switching to a different tab.

Does the JS need to be in a function and ran each time a tab is clicked? Can't seem to wrap my finger around this one.

Update: Narrowed it down to it absolutely being that the JS only get's run once, so only the first iFrame in the first tab gets all the correct variables and events bound to the elements.

Update: Seemed to have figured it out. While continuing to use iFrames, I had to throw all of my JS into a function and run it on $(".iframe").load() and whenever a new tab is click, for example, $(".nav-cont li a").bind("click",function(){ //run the javascript })


Solution

  • If you want to bind load event to two identical iframes:

    $("div.contents").delegate(".iframe", "load", function(){
       alert('one of the iframes loaded');
    });
    

    One handler function handles "load "event for both iframes.

    P.S. UPDATE You can't use iframes the way you explain in comments. Simply use divs instead and set overflow:hidden; If the intent is to limit the display size of that specific area with data - set this in css file:

    .form_container{width:500px;heigth:500px;overflow:hidden;}
    

    Your html then will be:

    <div class="tabs">
        <ul class="tabs-nav">
            <li><a href="#products">Products</a></li>
            <li><a href="#accessories">Accessories</a></li>
        </ul>
    </div>
    
    <div class="content">
        <div id="products">
            <div class="form_container">
                <form action="?" method="post">
                    <input type="checkbox" name="checkBox1" class="clickThisCheckBox" />
                </form>
            </div>
        </div>
    
        <div id="accessories">
            <div class="form_container">
                <form action="?" method="post">
                    <input type="checkbox" name="checkBox2" class="clickThisCheckBox" />
                </form>
            </div>
        </div>
    

    And js will be:

    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js" type="text/javascript"></script>
    <script type="text/javascript">
    $(document).ready(function(){
        $('form').find(':checkbox').click(function(){
            alert('something got clicked');
        })
    })
    </script>