0

In my homepage , I have this button.

<button class="test">test</button>

And in my current code I have this script

$('.test').on('click',function(){
        alert("YOU CLICKED ME");
    });

Now, my application is ajaxified, so everytime I click a new page it is loaded as ajax, the problem is that the loaded page also has this button. and its markup is likethis

<div id ="firstDiv>
   <div id ="secondDiv">       
  <button class="test">test</button>
  </div>
</div

So the new content also has "#test" but how come when I click that button it does not execute the event handler I created?

user962206
  • 15,637
  • 61
  • 177
  • 270
  • 1
    As you said, it's a new element. When you bind an event handler, it is only bound to *existing* elements. Btw, does this mean you have two buttons with the same ID? – Felix Kling Feb 08 '13 at 11:41
  • It sounds like you first need to make those `id` attributes in to classes before you run in to duplicates. You also want to google for delegate event handlers. – Rory McCrossan Feb 08 '13 at 11:41
  • then how do I bind existing events to upcoming elements? – user962206 Feb 08 '13 at 11:42
  • 1
    possible duplicate of [Events triggered by dynamically generated element are not captured by event handler](http://stackoverflow.com/questions/12829963/events-triggered-by-dynamically-generated-element-are-not-captured-by-event-hand) – Felix Kling Feb 08 '13 at 11:43
  • I've changed them to classes, also @FelixKling I already saw that but none of the answers worked for me – user962206 Feb 08 '13 at 11:44
  • It's hard to imagine that event delegation would not work. Make sure you are doing it right (have a look at the documentation). – Felix Kling Feb 08 '13 at 11:45
  • I am really wondering why it does not work. kinda odd in my opinion – user962206 Feb 08 '13 at 11:46

4 Answers4

3
var $bdy=$(document.body);     

$bdy.on('click','.test',function(){
    alert("YOU CLICKED ME");
});

now append your .test anytime you like

mikakun
  • 2,203
  • 2
  • 16
  • 24
0

So the new content also has "#test" but how come when I click that button it does not execute the event handler I created?

Because the handler is attached to the actual element. So if the element is removed and a new element with the same class is created, the event is not associated with that new element.

You could use event delegation to handle this:

$(document.body).delegate('.test', 'click', function(){
    alert("YOU CLICKED ME");
});

or

$(document.body).on('click', '.test', function(){
    alert("YOU CLICKED ME");
});

(They do the same thing, note the order of arguments is different. I prefer delegate for the clarity, but I think most people use the delegating version of the far-too-overloaded on method instead.)

What that does is watch for the click on document.body, but only fire your handler if the click passed through an element matching that selector (.test, in this case).

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
  • "As of jQuery 1.7, .delegate() has been superseded by the .on() method. " http://api.jquery.com/delegate/ – mikakun Feb 08 '13 at 11:49
  • @mikakun: Superceded, perhaps, but not deprecated. (jQuery has multiple ways of doing several things.) If they deprecate it, I'll keep using it. And if they remove it, I'll add it back (it's a one-liner). The jQuery API has far too much overloading of functions as it is. (If they actually deprecate it, though, I will stop using it in answers. In any case, I never *only* use it, I always explain about `on` as well.) – T.J. Crowder Feb 08 '13 at 11:52
  • i had no doubt you were aware of it, it was more intended to the op – mikakun Feb 08 '13 at 11:55
0

As you said that the content is loaded through data you get in AJAX this is the possible scenario that is happening.

  1. <button class="test">test</button> is drawn
  2. Then it is binded to to click event
  3. You load the new data through ajax
  4. Try to bind that it does not.

This is because when you first bind the click event to "test" element with that class are part of the DOM. Now that you add some markup after ajax call the elements become the part of DOM, but now after you wrote the new markup you need to first unbind the click event See Here. And then re-bind the click event. This will bind the event to all elements having class "test".

P.S. I don't know the specifications of your implementation but as others have suggested you should bind events to id and not class.

Jehanzeb.Malik
  • 3,332
  • 4
  • 25
  • 41
0

I finally found out the solution. all I needed to do was define a static container which is this

$('#staticdiv').on('click','.test',function(){
        alert("YOU CLICKED ME");
    });

and that fixed the issue

user962206
  • 15,637
  • 61
  • 177
  • 270