Loading PHP file into DIV via AJAX

Started by
3 comments, last by Ubik 10 years, 11 months ago

Hi everyone,

This is another n00b question but here goes...

Say I have an index.php that loads a page.php into one of its divs. So:

$('#result').load('page.php');

page.php in turn has its own links and I want it so that when you click on one of these links it loads the respective page into the SAME #result div. Similarly that loaded page might have its own links and I want to continue loading content into the same div. How might I achieve this chain effect of pages?

Thank you for your time.

Advertisement

$('#result a').on('click', function() {
    $('#result').load($(this).attr('href'));
    return false;
});

Something like that? That will load the page the anchor links to. This affects all anchors in the div though, you might want to change the selector to only affect a specific class.

Without having tested the code, Navall's solution looks otherwise good to me, but has a piece missing - you will have to re-setup the click handlers within a callback passed to load, because as the content of #result gets replaced, the new content will have no handlers set for any elements. This gets easily messy, because essentially you have to setup the click handler doing a load() within the callback of the said load().
However, there's an easier way: jQuery's on() allows you to attach the handler to the container element* with an additional selector that limits the handler to specific elements within the container:

// "#result a" has just been split into "#result" and "a"
$('#result').on('click', 'a', function() {
    $('#result').load($(this).attr('href'));
    return false;
});

* I'm assuming the element #result doesn't get replaced by DOM manipulation or load() or other change, as the idea is to attach the handler to a static element. It's good idea always to attach the handler to the innermost unchanging element, for example to #result in this case.

Thanks for the replies!

Ubik: What do you mean by "#result a" has just been split into "#result" and "a"?

Also why is it .load($this) and not .load(page.php)??

The JavaScript comment was there to draw attention to how the selectors have changed between the examples.

In the original example there was $('#result a'), which would return the links within the #result element. The modified example was split into $('#result') which returns just the container element. The on() after it, used to bind the click handler, results with the handler being actually bound to the #result element. That is why the handler would survive even if the contents of the container were replaced by load(). The second parameter to on() is just 'a', and acts as a second search filter that is executed against (or actually within) the results of the "regular" jQuery query earlier on the line that was used to find #result. It is the thing that makes sure the click handler you are binding to #result is actually only executed when a link in #result is being clicked.

Regarding the second question, maybe I should break the code down a bit. It could have been done like this:


$('#result').on('click', 'a', function() {
    var url = $(this).attr('href');
    $('#result').load(url);
    return false;
}); 

The click handler has a special variable named this defined within it, and it refers to the element that was clicked. However, you can't use jQuery functions against it directly, you need to use the $(this) form. With that, the attr('href') is called, to get the URL the clicked link is pointing at. That URL is then given to load(). If "page.php" was used, any link within the loaded content would ever only point to page.php. Your original post suggests that the links could point to other pages as well. Even if they didn't, hardcoding the URL is not recommendable, when you can just make the link have a proper URL in its href and use it.

Edit: Addition to the first part. There is a parallel with the "two-part" selection with jQuery's function find(). Doing $('#result a') is functionally equivalent to $('#result').find('a'). They both return the links within #result. However, with on() there is an important difference: the selector given to it is not executed immediately. Only when the #result receives a click (remember, the handler is actually bound to it) it runs the second selector to see if the click hit a matching element within the container. In this case, a link.

This topic is closed to new replies.

Advertisement