tags:

views:

359

answers:

3

So I have some code and I add an element to the DOM after pageload (the second link in the below example) however this newly added element ignores all functions defined for it. So for the example below I want all links in div's with the test class to show an alert. Works fine for the link hard coded but the one added afterwards ignores it.

<html>
    <head>
        <title>SO Test</title>
        <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"&gt;&lt;/script&gt;
    </head>
    <body>
        <div class="test">
            <a href="#" title="Test">Test Link</a>
        </div>
        <script type="text/javascript">
        <!--    
            $(document).ready(function() {

                $("div.test a").click(function() {
                    alert("click");
                    return false;
                });

                $(document.createElement("a")).attr("href","#").text("Test Link 2").appendTo("div.test");

            });
        -->
        </script>
    </body>
</html>

EDIT: Is the only solution to abstract it away with a jQuery plugin?

A: 

Your code can be cleaned up and act like you're hoping like this:

<html>
    <head>
        <title>SO Test</title>
        <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"&gt;&lt;/script&gt;
    </head>
    <body>
        <div class="test">
            <a href="#" title="Test">Test Link</a>
        </div>
        <script type="text/javascript">
        <!--    
            $(document).ready(function() {

                $("div.test a").live('click', function() {
                    alert("click");
                    return false;
                });

                $('<a href="#">Test Link 2</a>').appendTo("div.test");

            });
        -->
        </script>
    </body>
</html>
Agent_9191
That will only work in the same manner assuming there are no other links anywhere on the page, thought it would be fairly obvious that I dumbed down an example...
Andrew G. Johnson
So narrow your selector. It will only apply to any link that is added within your <div class="test">.
Agent_9191
I'm not trying to duplicate a link, I am trying to create a new one from scratch hence I'd like my code to reflect this
Andrew G. Johnson
Just edited it. Realized where it was wrong.
Agent_9191
the idea behind `.live()` is that it adds an event listener to the document which never changes, and with event delegation it fires only if the selector chosen is clicked or any other event specified
adardesign
+3  A: 

IF you use jquery live that will take care of that problem. jquery live Binds a handler to an event (like click) for all current and future matched element.

 $("div.test a").live("click", function(){ //change to this

});
TStamper
If your using jQuery 1.2.6 or older you can still have the same functionality by using a plug-in called liveQuery http://docs.jquery.com/Plugins/livequery
adardesign
+1  A: 

Your issue is that click() binds an event listener to each element in the current matched set. It's not magic, and it won't retroactively apply the event listener to new content you add to the DOM. Your options are:

  1. Use the live events functionality in jQuery, as others have mentioned.
  2. Do something similar yourself, by binding a click handler to some common ancestor of the elements in which you're interested, and then testing the target of each click you see to determine whether you care about it. For example:
    $(function(){
      $("div.test").click(function(e){
        if( $(e.target).is("a") ) {
          alert("click");
          return false;
        });
      });
    });
  3. In the code that adds the new elements to the DOM, also bind event handlers to them. For example:
    $(document.createElement("a"))
      .attr("href","#")
      .text("Test Link 2")
      .click(function(){ alert("click"); })
      .appendTo("div.test");
Sixten Otto
Accepted since I think you cover all my options
Andrew G. Johnson