简体   繁体   中英

.on() not working for dynamically generated content

I'll try and explain what I'm trying to do as clearly as I can and hopefully people'll be able to understand the issue.

$(document).ready(function() {
  $('body').on('click', '.mainNav', function() {
    var href = $(this).attr('href');
    $('body').load(href);
   });
});

This is the bit of code which has been causing me trouble. Basically what it's -supposed- to do is grab the 'href' attribute from a div and then load that to replace the current content of the body tag.

This works the first time but when the new content is generated via .load() the div stops responding. I'm pretty new to JS so I apologize in advance if the answer is something obvious. I've been trying to find a solution on my own but everything I find tells me that .on() should work for dynamically generated content.

EDIT: Can't emulate the problem in a fiddle so I'm posting a pastebin with the entire index page in hopes of it clarifying the problem.

http://pastebin.com/xT5syd9j

EDIT: It works using adeneo's solution. Much obliged to everyone for their input and apologies for not posting the entire thing from the start. I'm guessing it would've saved everyone some time.

The problem here may be what you really load when you invoke $('body').load(href) . If you load the HTML of the whole page (including <html> and <body> tags), then you may have a problem. Your browser works with such issues by making something usable from incorrect HTML (which is in your case something like <html><body><html><body>...</body></html></body></html> ) - which may give unexpected results.

The better idea is to:

  1. Organize HTML properly (see below)
  2. Load only part of the HTML generated above, when you load it with $(...).load() .

Ad.1. Make sure you have some element just below <body> tag, that has own ID and contains everything that would be located in <body> tag. It may look like that:

<html>
...
<body>
    <div id="main_div">
    <!-- all elements here -->
    </div>
</body>
</html>

Ad.2. Loading such content is a lot easier, as you can append a selector to the URL passed to .load() (see " Loading Page Fragments " on jQuery .load() docs page ):

$('body').load(href + ' #main_div');

This way you will retrieve whole page, but get only the element with ID " #main_div " and replace the whole <body> content with it.

This way events attached to body (even these delegated) should still work properly.

Not really sure what the issue it, but I'm guessing it has something to do with loading into the same element as the handler is attached to, so try :

$(document).ready(function() {
    $(document).on('click', '.mainNav', function(e) {
        e.preventDefault();
        console.log('I just clicked : '+e.target.href);
        $('body').load(e.target.href);
    });
});

Also, you are of course aware that this will replace ALL content on your page, and unless there is a new element with the same class in the loaded content, nothing will happen. I would suggest using a container for loading the content into aswell. And of course, the links has to be to actual files on your server.

Also make sure the files you load does not have another set of <head> , <body> tags etc. as that will mess things up for you, HTML content only!

EDIT:

If .mainNav is a <a href="link_you_are_trying_to_load"></a> type of element, you will have to prevent the default action as well, see updated code.

NEW EDIT:

The problem you are having is pretty obvious, you are using elements like :

<div class="mainNav" href="test.php" id="active">

a div element has no attribute href, so JS will not get that value as it's not a valid attribute for anything other than a <a> element

You can either change your element to an <a> element or change the href attribute to:

<div class="mainNav" data-href="test.php" id="active">

and do:

var href = $(this).data('href');

at least that would be valid HTML!

Also, you seem to have a "container" like element called #site so why don't you do :

$('#site').load(href); //using the data-href as above

Try this:

$(document).ready(function(){
    $('body').on('click', '.mainNav', function() {
        var href = $(this).attr('href');
        $('body').load(href + " body > *");
    });
});

What we do here is load only the contents of the body element on the page ( href ). There's no need to add more elements to that page. Just select the contents of the body like Tradeck mentioned.

The problem is obviously that if the page at href is a full HTML page, you're loading in a DOCTYPE, a second html tag, a second head and body tag, etc.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM