0

I have the following php pages main.php content.php

main.php

When the user clicks a link the content.php page is loaded in a div in main.php page.The main.php when loaded contains a separate script file that has scripts for content.php page. The script works fine when I include it in the content.php but does not work when i place it in a separate file in the head section of main.php What is the reason for this?

JS File

$(function(){
    $('#new').click(function(event){
        event.preventDefault();
        $('#content').load('content.php');
    });
    $('#rank').click(function(event){
        alert("This works!!");
        event.preventDefault();
    });
});

main.php

 <div id="container">
            <div id="header">
            </div>
            <div id="nav">
               <a href="#" id="new">New Page</a>
            </div>
            <div id="content">
    /*** Pages get loaded Here ***/
            </div>
            <div id="footer">
            </div>
        </div>

content.php

<a href="#" id="rank">jQuery Test</a>
AAB
  • 1,594
  • 2
  • 25
  • 40
  • 1
    did you included original link to jquery and js file in main.php ? – Aadil Keshwani Feb 19 '15 at 08:23
  • Yes link to Jquery library and my js file are included in the head section of main.php – AAB Feb 19 '15 at 08:24
  • 1
    can you add that code here ? – Aadil Keshwani Feb 19 '15 at 08:24
  • Can you also mention the error you see? The anchor element in content.php may not be available to main.php at the time of adding click event handler. – Annapoorni D Feb 19 '15 at 08:27
  • Best practice are to put this link at the end of your html or php file : it let the DOM load and will download the js files at end of the render – Tony Feb 19 '15 at 08:27
  • @Tony Hi well I read a stackoverflow answer that mentioned putting it in the head as a better option as it blocks page load till the scripts are downloaded completely – AAB Feb 19 '15 at 08:29
  • 1
    [You need to use event delegation for dynamically added elements](http://stackoverflow.com/questions/203198/event-binding-on-dynamically-created-elements) – Spokey Feb 19 '15 at 08:30
  • @Spokey could you explain? – AAB Feb 19 '15 at 08:30
  • @SpreeTheGr8 No error but thats what I thought – AAB Feb 19 '15 at 08:31
  • Yes, I linked to the one of the questions that was asked on SO. Using `.on()` in that way will work for any elements that you add after the DOM is ready. – Spokey Feb 19 '15 at 08:34
  • @Spokey So .on() adds event handlers for elements that are added to the page after page loads completely? – AAB Feb 19 '15 at 08:36
  • Yes, you already got an answer below with the right format – Spokey Feb 19 '15 at 09:03

2 Answers2

2

Well that is the problem because you are using the

$(function(){ }

Which is similar to $(document).ready(). This will only recognise the things that load before the $(document).ready() is excecuted.

In order for the new content to call the jQuery code you need to use the

$(document).on() Command:

 $(document).on('click', '#new', function(){
        event.preventDefault();
        $('#content').load('content.php');
})  
.on('click','#rank', function(event){
    alert("This works!!");
    event.preventDefault();
 });
Ideal Bakija
  • 629
  • 5
  • 14
2

This is a very common question, unfortunately way too common, and has been answered many times before.

You have to understand asynchronism.

When you bind $('#rank').click in your init function, $('#rank') does not exist yet. It's not originally in your DOM. It will be created a few moments later, when the load() function ends, which takes some time (even a few milliseconds).

So $('#rank').click(... does not do anything.

Then $('#rank') is being created.

Now there are two solutions :

1) Wait for $('#rank') to be created, THEN bind a click to it :

$('#content').load('content.php', function(){
     // this is the callback function. It will be executed after the load() finishes and content.php is fetched.

    $('#rank').click(function(event){
        alert("This works!!");
        event.preventDefault();
    });
})

2) anticipate and listen for the creation of $('#rank')

By using $('document').on('click','#rank', function(..., you set a listener that is going to wait for any $('#rank') element to be created. As soon as it happens, it will execute the function. It works for present and future elements.

Jeremy Thille
  • 26,047
  • 12
  • 43
  • 63