75

Here's index.html:

<head>
  <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.5.2/jquery.min.js"></script>
  <script type="text/javascript">

    $(document).ready(function() {
      $('.btn_test').click(function() { alert('test'); });
    });

    function add(){
      $('body').append('<a href=\'javascript:;\' class=\'btn_test\'>test</a>');
    }

  </script>
</head>
<body>
  <a href="javascript:;" class="btn_test">test1</a>
  <a href="javascript:;" onclick="add()">add</a>
</body>

If I click on test1 link, it shows alert('test'), but if I click on add link then click on test, it doesn't show anything.

Could you explain it?

ekremkaraca
  • 1,453
  • 2
  • 18
  • 37
Ralsk28
  • 769
  • 1
  • 6
  • 3

13 Answers13

214

For users coming to this question after 2011, there is a new proper way to do this:

$(document).on('click', '.btn_test', function() { alert('test'); });

This is as of jQuery 1.7.

For more information, see Direct and delegated events

V31
  • 7,626
  • 3
  • 26
  • 44
Moshe Katz
  • 15,992
  • 7
  • 69
  • 116
  • 2
    Wish I could select the answer as an 'Accepted answer'. Thank you for saving my (remaining) day! – sohaiby May 23 '14 at 12:25
  • 1
    I just kept on unbinding() and rebinding methods on my whole project before I saw this. Where's the guy who asked this? Man, accept it. – Unrealist Nov 13 '14 at 14:26
  • Fascinating and cool! Thanks for adding this clarification. Fixed a vexing issue for me. – tonejac Apr 12 '15 at 17:12
  • You should add that the proper way to solve this is by adding the "selector" parameter. I figured it out after reading the link but not because of your answer. Still I'm thankful :) @Moshe Katz – villancikos Sep 05 '15 at 20:45
  • $(document) is fine but for best performance it would be better to use $("#element") or $(".class") instead - where the element or class already exists in the dom. Instead of having jquery watch the entire document, it will only watch the #element or .class. – Eric Kigathi May 17 '17 at 20:21
34

You need to use a "live" click listener because initially only the single element will exist.

$('.btn_test').live("click", function() { 
   alert('test'); 
});

Update: Since live is deprecated, you should use "on()":

$(".btn_test").on("click", function(){ 
   alert("test");
});

http://api.jquery.com/on/

Doug Molineux
  • 12,283
  • 25
  • 92
  • 144
  • 3
    Yes, to clarify - `live` is a late-binding dynamic handler that can attach to elements added to the DOM after the handler is declared. See [this documentation](http://api.jquery.com/live/) for more info. – chrisfrancis27 Jun 30 '11 at 15:38
  • 2
    Another way of stating this is: `.click()` will only apply to objects that exist when the page is loaded, but `.live()` will apply to all objects that exist now or are created in the future. – George Cummins Jun 30 '11 at 15:39
  • i got a new question how can i use live method with this ->http://www.steamdev.com/zclip/ – Ralsk28 Jun 30 '11 at 16:01
  • 1
    @Ralsk28: If this answer helped you, you can reward Pete by upvoting the answer and clicking the check to accept it. This will also help future visitors to the site find solutions to their own problems. – George Cummins Jul 01 '11 at 14:15
  • 2
    live() is now deprecated isnt it? what is the alternative? – Chris Jun 07 '12 at 11:44
15

I have same problem like question I was just near to pulling my hair then i got the solution. I was using different syntax

$(".innerImage").on("click", function(){ 
alert("test");
});

it was not working for me (innerImage is dynamically created dom) Now I'm using

$(document).on('click', '.innerImage', function() { alert('test'); });

http://jsfiddle.net/SDJEp/2/

thanks @Moshe Katz

Umer Farooq
  • 388
  • 3
  • 18
8

.click binds to what is presently visible to jQuery. You need to use .live:

$('.btn_test').live('click', function() { alert('test'); });
CassOnMars
  • 6,153
  • 2
  • 32
  • 47
7

Use Jquery live instead. Here is the help page for it http://api.jquery.com/live/

$('.btn_test').live(function() { alert('test'); });

Edit: live() is deprecated and you should use on() instead.

$(".btn_test").on("click", function(){ 
   alert("test");
});
Amir Raminfar
  • 33,777
  • 7
  • 93
  • 123
3

This is because you click event is only bound to the existing element at the time of binding. You need to use live or delegate which will bind the event to existing and future elements on the page.

$('.btn_test').live("click", function() { alert('test'); });

Jquery Live

V31
  • 7,626
  • 3
  • 26
  • 44
scrappedcola
  • 10,423
  • 1
  • 32
  • 43
2

you need live listener instead of click:

$('.btn_test').live('click', function() { 
   alert('test'); 
});

The reason being is that the click only assigns the listener to elements when the page is loading. Any new elements added will not have this listener on them. Live adds the click listener to element when the page loads and when they are added afterwards

locrizak
  • 12,192
  • 12
  • 60
  • 80
1

After jquery 1.7 on method can be used and it really works nice

<!DOCTYPE html>
<html>
<head>
    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.1/jquery.min.js">
    </script>
<script>
    $(document).ready(function(){
      $("p").on("click",function(){
       alert("The paragraph was clicked.");
       $("body").append("<p id='new'>Now click on this paragraph</p>");
    });
    $(document).on("click","#new",function(){
       alert("On really works.");
      });
    });
</script>
</head>
<body>
    <p>Click this paragraph.</p>
</body>
</html>

see it in action http://jsfiddle.net/rahulchaturvedie/CzR6n/

Rahul
  • 21
  • 1
1

When the document loads you add event listeners to each matching class to listen for the click event on those elements. The same listener is not automatically added to elements that you add to the Dom later.

shanethehat
  • 15,460
  • 11
  • 57
  • 87
1

Because the event is tied to each matching element in the document ready. Any new elements added do NOT automatically have the same events tied to them.

You will have to manually bind the event to any new element, after it is added, or use the live listener.

Neil N
  • 24,862
  • 16
  • 85
  • 145
1
$('.btn_test').click

will add the handler for elements which are available on the page (at this point 'test' does not exist!)

you have to either manually add a click handler for this element when you do append, or use a live event handler which will work for every element even if you create it later..

$('.btn_test').live(function() { alert('test'); });
Karoly Horvath
  • 94,607
  • 11
  • 117
  • 176
0

Or just run the script at the end of your page

Enigmax
  • 59
  • 4
0

You need to add a proper button click function to give a proper result

$("#btn1").live(function() { alert("test"); });
Yannick
  • 813
  • 8
  • 17