24

I am having trouble getting an .on 'click' function to work upon AJAX loaded content.

I have worked with the jquery .live before but this is the first time with .on and understand it works in the exact same way so unsure why I am having problems.

Below is the HTML that gives the element to which you click on

    <h1>Press &amp; Media</h1>
    <div id="back"></div>
    <div id="overlay-content">
        <span id="edocs" class="tab"></span>
        <span id="news" class="tab"></span>
        <span id="partners" class="tab"></span>
    </div>

Below is the function that loads the AJAX content.

    $("#overlay-content").on('click','#news',function() {
        var active = 1;
        $("#loading").show();
        $("#overlay-content").fadeOut(1000, function() {
            $.get("http://<? echo ROOT; ?>includes/functions.php", { pressmediaNews: active }, function(data) {
                $("#loading").hide(400);
                $("#overlay-content").empty().append(data).fadeIn(1000);
            });
        });
    });

This should load the following HTML

    <div id="news-left-panel">
        <h4>News Section</h4>
        <ul>
            <li id="newsID2" class="newsYear">
                <p>2012</p>
                <ul class="newsMonths" style="display:none">
                    <li>Jan
                        <ul class="newsArticles" style="display:none">
                            <li onClick="newsID(2)">test</li>
                        </ul>
                    </li>
                    <li>Feb</li>
                    <li>Mar</li>
                </ul>
            </li>
            <li id="newsID1" class="newsYear">
                <p>2011</p>
                <ul class="newsMonths" style="display:none">
                    <li>Dec
                        <ul class="newsArticles" style="display:none">
                            <li onClick="newsID(1)">Test</li>
                        </ul>
                    </li>
                </ul>
            </li>
        </ul>
    </div>

Now the above code simply wont execute, show any errors etcetera in firebug.

So I'm a bit lost as to why it wont execute, the alert() even does not execute.

7
  • Whats the container html element look like that you are inserting your dynamic content into? Commented May 2, 2012 at 15:21
  • edited orginal post to reflect your ask. Commented May 2, 2012 at 15:30
  • Have you got an online example of this? I implemented your code exactly locally and it appears to work as it should. milliamp.org/test/10416689 (#news is the blue box) Commented May 13, 2012 at 13:24
  • Important note: you will need jQuery 1.7.0 or above, so if you use older version than that, it cannot work. Commented May 17, 2012 at 8:31
  • Based on the question and answers, it seems we are missing something else in your question details or the exact situation. Perhaps cross domain issue? Is your site https and this uses http?No content in "tab" #news to click shown here. Can you reproduce in a test environment? I think we need to know what part of this we are missing that is needed to be known. IF I simply use a string instead of your "get" using your return as the string, it does work. Commented May 17, 2012 at 13:39

7 Answers 7

41
+50

First make sure you're hitting the target, try this and see if the alert shows :

$(function() {
    $(document).on('click', '#news', function() {
       alert('ok');
    });
});

If the alert shows when clicking the #news element, it's ok.

Now to this line:

$.get("http://<? echo ROOT; ?>includes/functions.php",

You are using the shorthand PHP opening, and that needs to be turned on, you could try

<?php echo ROOT; ?>

But what the frack is ROOT, never seen that before, and could not find anything in the PHP manual on ROOT, so I tried on my own server with the newest version of PHP, and got an error as 'ROOT' does not exist, instead it assumed it was a string and just echo'ed "ROOT", so your link would look like:

$.get("http://ROOTincludes/functions.php",

It it's a variable you have defined somewhere yourself, it should start with a dollarsign, if it's something you've defined with define(), make sure it's set up correctly and if it's using something like $_SERVER['DOCUMENT_ROOT']; that's not always something you can access in javascript as it will normally be a folder that is higher then your webroot, and can't be accessed on the clientside but only on the serverside.

Also, the way you have written it, starting with http:// it should be a domain name. Try opening view source in you browser and find your ajax function and see what ROOT actually outputs, as the final ouput will be visible in the source, and if it's set using define() in an included config file etc. you can see that it was set up correctly.

Your javascript would also have to be inside a PHP file for PHP to execute, or you would have to modify your server setup to run JS files thru PHP.

In my opinion just using a path and filename is the right way to do it, try this and pay attention to the console (F12) :

$(document).on('click','#news',function() {
    var active = 1;
    var XHR = $.ajax({
                   type: 'GET',
                   url : '/actualpath/includes/functions.php',
                   data: { pressmediaNews: active }
              }).done(function(data) {
                   console.log(data);
              }).fail(function(e1, e2, e3) {
                   console.log('error : '+e1+' - '+e2+' - '+e3);
              });
    $("#loading").show();
    $("#overlay-content").fadeOut(1000, function() {
        XHR.done(function(data) {
            $("#overlay-content").empty().append(data).fadeIn(1000);
            $("#loading").hide(400);
        });
    });
});
Sign up to request clarification or add additional context in comments.

5 Comments

sorry for the massive delay in response I have been in hospital and unable to reply to any messages since I placed the bounty :(. I tried your first snipet of code and that did not call the alert back so i guess the problem lies there. In response the ROOT command; that is a php define that uses $_server['HTTP_HOST'].
No problem. If the alert does not show, something is wrong with your JS. Try doing ​$(function() { alert('ok'); }​);​ to see if jQuery is loaded at all, if it is, the problem almost certainly is that the #news element is not inserted, or inserted wrongly and does not somehow exist.
jQuery definitely loads up as it runs lots of other queries on page load. So it must be something to do with the #new element.
Ihave decided to come away from this approach and try something totally different, thank you very much for all your help.
This answer had solved a lot of issues i was having, despite my code was totally different. thanks and thumbs up.
10

Use a delegate:

$('#overlay-content').on('click', '#newsID2', function() { });

This will bind the event on #overlay-content and check for bubbled events if they originated from #newsID2.


As a side-note: You have a typo in your event handler (chikdren should be children) and you should really get rid of this ugly onClick inline event.

7 Comments

Thaks for the speedy reply. I have added the code you suggest, i have changed the '#newsID2' to '.newsYear' as a class would be required past the testing phase. Sadly though it does not work as intended.
Also I do feel as though using onClick is outdated, so what would you recommend to replace that why of working the event?
@Daniel, it's still good if you don't intend to do sophisticated stuff within that bound function and/or change this onClick handler itself.
I would put the ID in a data- attribute and would access that from within a delegated event.
Anyone able to take this further? the help offered so far is appreciated but has not been successful in fixing the problem.
|
5

Should be more like:

$("#overlay-content").on('click', '#newsID2', function() {
    ....
});

Or in other words:

$('.wrapper').on('event', '.target', function() {
    ...
});

Where .wrapper is an element that already exists (or the document), and .target is the element(s) inside the wrapper you want to run the event on.

The live function is basically equivalent to:

$(document).on('event', '.target', function() { 
    ... 
});

2 Comments

Thank you for outlining the core fuinctionality of the .on() as with @ThiefMaster 's reply using that fix does not change anything.
This was the fix that solved the exact same problem you're having for me. At this point it'd probably need to be more hand on troubleshooting.
3

http://bugs.jquery.com/ticket/11203

Key sentence

If new HTML is being injected into the page, select the elements and attach event handlers after the new HTML is placed into the page.

To work with this scenario try binding to the document object with a selector parameter:

$(document).on('click','#news',function() {...}

1 Comment

Hi @Rockitsauce, thank you for taking the time to help. I have just tried changing the target element to document but it still did not make any effect. Any other ideas?
0

Since you said that you have previously worked with .live() could the issue here be that you're trying to bind your click on something that you append to the document before you append it?

When you use live, it handles this sort of stuff automatically, but when you don't use live, things generally have to exist on the page before you bind any events to them. If you add something with AJAX, you can't set up click events for those things before you've loaded them in with AJAX. When you use .live() you can do this ahead of time.

I would do it like this:

$("#overlay-content").on('click','#news',function() {
        var active = 1;
        $("#loading").show();
        $("#overlay-content").fadeOut(1000, function() {
            $.get("http://<? echo ROOT; ?>includes/functions.php", { pressmediaNews: active }, function(data) {
                $("#loading").hide(400);
                $("#overlay-content").empty().append(data).fadeIn(1000);

                //put your delegate/call/function,etc here

            });
        });
    });

1 Comment

sadly the delegate .on event still wont execute.
0

News-left-panel

year_Month_newsID Your News's Year, Month, News ID. For example 2012_5_16, 2012_5_17 etc

<div id="news-left-panel">
    <h4>News Section</h4>
    <ul>
        <li id="newsID2" class="newsYear">
            <p>2012</p>
            <ul class="newsMonths" style="display:none">
                <li>Jan
                    <ul class="newsArticles" style="display:none">
                        <li id="year_Month_newsID">test</li>
                    </ul>
                </li>
                <li>Feb</li>
                <li>Mar</li>
            </ul>
        </li>
        <li id="newsID1" class="newsYear">
            <p>2011</p>
            <ul class="newsMonths" style="display:none">
                <li>Dec
                    <ul class="newsArticles" style="display:none">
                        <li id="year_Month_newsID">Test</li>
                    </ul>
                </li>
            </ul>
        </li>
    </ul>
</div>

Jquery Function

$("#news-left-panel ul li").live("click", function(event) {
            var news=(this.id).split("_");
            var year=news[0];
            var month=news[1];
            var newsID =news[2];

            $.ajax({
                type: "POST",
                url: 'http://<? echo ROOT; ?>includes/functions.php',
                data: {
                    year: year,month:month,newsID :newsID
                },
                error: function(){
                    $('#news').html( "<p>Page Not Found!!</p>" );
                    // Here Loader animation
                },
                beforeSend: function(){
                    // Here Loader animation
                    $("#news").html('');
                },
                success: function(data) {
                    $('#news').html(data);

                }
            });
        });​

3 Comments

The live method is deprecated, and shouldn't be used. From the docs: "As of jQuery 1.7, the .live() method is deprecated. Use .on() to attach event handlers. Users of older versions of jQuery should use .delegate() in preference to .live()."
Thanks for advise. Your right. I difference understood on(),delegate(), blind(). jsperf.com/jquery-live-vs-delegate-vs-on
I voted down because i don't like such complex ansvers with a lot of BOLD UPPERCASE text
0

Are you sure your Ajax call is correct / returning the right HTML?

I replaced $.get() with setTimeout() (and simplified a bit) here: http://jsfiddle.net/q23st/

It seems to work, so I suspect your $.get() isn't returning what it's expected to return.

1 Comment

The problem is that the .on 'click' event is not executing, as a simplified version which just executes an alert command wont work either.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.