Tomas Novotny
Tomas Novotny

Reputation: 8327

Dynamically adding content to HTML page using JavaScript (and JQuery) - how to access new content?

I have a HTML file that contains only the basic elements (html, head, body, ...) and I want to fill it up with content stored in an external file ("content.html") in my case, using JavaScript (and JQuery). I have accomplished that with function $.get(), but I don't know, how to access the information I got with this function.

For example, I want to throw an alert if a link is clicked. My code looks like this:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html>
<head>
    <meta http-equiv="content-type" content="text/html; charset=UTF-8">
    <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3/jquery.min.js"></script>

    <script type="text/javascript">
    $(document).ready(function(){

       $.get("content.html", addContent);   // calls addContent

       function addContent(data)            // fills <div id='content'> with content.html
       {
          $("#content").html(data);
          alert('Load was performed.');
       }


       $("a").click(function(event){ // !!!if any link is clicked, throw an alert 
         alert("Link clicked");
         event.preventDefault();
       });

     });
    </script>

</head>

<body>
  <div id="content">
  <!--CONTENT OF content.html WILL BE INSERTED HERE-->
  </div>
</body>
</html>

This is how content.html looks like:

<h1>Band Creator Home</h1>
    <p>Currently following apps are available:</p>
    <ul>
        <li><a href="/bands/">Bands</a></li>
        <li><a href="/instruments/">Instruments</a></li>
        <li><a href="/musicians/">Musicians</a></li>
        <span></span>
    </ul>

Since there is no element in the original HTML, alert "Link clicked" is never thrown. How can I access these elements collected by $.get() ?

Upvotes: 2

Views: 4393

Answers (4)

Guffa
Guffa

Reputation: 700790

There are some different ways. You can set the events after loading the content:

function addContent(data) {
  $("#content").html(data);
  alert('Load was performed.');
  $("#content a").click(function(event){
    alert("Link clicked");
    event.preventDefault();
  });
}

You can use the live method to catch the even when it bubbles up:

$("a").live('click',function(event){
  alert("Link clicked");
  event.preventDefault();
});

If you are using version 1.4.2 or later of jQuery, you can use the delegate method, which is like the live method, but you can check for bubbling events in a closer scope than the body:

$("#content").delegate('a', 'click',function(event){
  alert("Link clicked");
  event.preventDefault();
});

Upvotes: 1

MartinStettner
MartinStettner

Reputation: 29174

An alternative to the live method is using delegate on some parent of the newly created elements. This is useful if you don't want the event to be propagated to the top of the DOM hierarchy.

$("#parentofa").delegate("a", "click", function(event) {
    // ... my handler
    event.preventDefault();
})

The <a> element that was clicked is stored in event.target

Note that preventDefault is working here but that the event has already been propagated until the parent element (i.e. all elements in between have received the element already)

Upvotes: 1

jAndy
jAndy

Reputation: 236162

You are looking for .live() bindings. Do it like:

$("a").live('click', function(event){ // !!!if any link is clicked, throw an alert 
     alert("Link clicked");
     return false;
});

The event method .preventDefault() does not work within .live(), return false instead. Since .live() adds an even listener to the document.body, it's always a good idea to use .delegate() if possible. You can tell .delegate the closest parent node which all elements share you need to watch. In your instance:

$('ul').delegate('a', 'click', function() {
     alert('Link Clicked');
     return false;
});

Ref.: .live(), .delegate()

Upvotes: 3

SLaks
SLaks

Reputation: 888187

AJAX is asynchronous.
The server only sends a reply some time after the get method finishes.

Therefore, you end up adding the click handler before addContent is called, before the new elements exist.
If you add the handler inside addContent, it will work fine, since the new element will have already been added.

Alternatively, you can use jQuery's live method to add a handler to all elements that match the selector, no matter when they were created.

Upvotes: 2

Related Questions