By frankadelic


2009-08-31 19:29:03 8 Comments

Suppose I have some jQuery code that attaches an event handler to all elements with class .myclass.

For example:

$(function(){
    $(".myclass").click( function() {
        // do something
    });
});

And my HTML might be as follows:

<a class="myclass" href="#">test1</a>
<a class="myclass" href="#">test2</a>
<a class="myclass" href="#">test3</a>

That works with no problem. However, consider if the .myclass elements were written to the page at some future time.

For example:

<a id="anchor1" href="#">create link dynamically</a>
<script type="text/javascript">
$(function(){
    $("#anchor1").click( function() {
        $("#anchor1").append('<a class="myclass" href="#">test4</a>');
    });
});
</script>

In this case, the test4 link is created when a user clicks on a#anchor1.

The test4 link does not have the click() handler associated with it, even though it has class="myclass".

Basically, I would like to write the click() handler once and have it apply to both content present at page load, and content brought in later via AJAX / DHTML. Any idea how I can fix this?

8 comments

@Chandler Zwolle 2014-07-15 20:28:56

Sometimes doing this (the top-voted answer) is not always enough:

$('body').on('click', 'a.myclass', function() {
    // do something
});

This can be an issue because of the order event handlers are fired. If you find yourself doing this, but it is causing issues because of the order in which it is handled.. You can always wrap that into a function, that when called "refreshes" the listener.

For example:

function RefreshSomeEventListener() {
    // Remove handler from existing elements
    $("#wrapper .specific-selector").off(); 

    // Re-add event handler for all matching elements
    $("#wrapper .specific-selector").on("click", function() {
        // Handle event.
    }
}

Because it is a function, whenever I set up my listener this way, I typically call it on document ready:

$(document).ready(function() {
    // Other ready commands / code

    // Call our function to setup initial listening
    RefreshSomeEventListener();
});

Then, whenever you add some dynamically added element, call that method again:

function SomeMethodThatAddsElement() {
    // Some code / AJAX / whatever.. Adding element dynamically

    // Refresh our listener, so the new element is taken into account
    RefreshSomeEventListener();
}

Hopefully this helps!

Regards,

@DKMudrechenko 2015-03-23 00:04:09

Thanks! Couldn't get it to work with other answers, your solution worked like a charm, however if I call RefreshSomeEventListener() after adding dynamic element, my event is triggered twice

@Ryan Steffer 2017-04-12 17:30:54

@DKMudrechenko Likely this is because you're not fully removing the event listeners from it.

@Sean 2012-02-17 15:37:53

I am adding a new answer to reflect changes in later jQuery releases. The .live() method is deprecated as of jQuery 1.7.

From http://api.jquery.com/live/

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().

For jQuery 1.7+ you can attach an event handler to a parent element using .on(), and pass the a selector combined with 'myclass' as an argument.

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

So instead of...

$(".myclass").click( function() {
    // do something
});

You can write...

$('body').on('click', 'a.myclass', function() {
    // do something
});

This will work for all a tags with 'myclass' in the body, whether already present or dynamically added later.

The body tag is used here as the example had no closer static surrounding tag, but any parent tag that exists when the .on method call occurs will work. For instance a ul tag for a list which will have dynamic elements added would look like this:

$('ul').on('click', 'li', function() {
    alert( $(this).text() );
});

As long as the ul tag exists this will work (no li elements need exist yet).

@user673046 2013-08-11 19:49:48

This otherwise brilliant solution seems to have a problem with HTML content living in a Fancybox. I've reverted to creating the handlers for that manually. I didn't try iFrame Content yet, so the content of the fanyxbos is part of the body or in my case of the document variable.

@Satya Prakash 2013-12-21 14:36:06

live() is deprecated and .on() came. But it is not clear that when I write $('selector').on('event', callback(){}) then it wont work. Need to write desired selector inside on(). $(document).on('event', 'selector', callback(){}) or, $('body').on('event', 'selector', callback(){})

@Juan 2014-04-29 19:38:38

what about performance? is it the same as attaching events directly?

@Mostafa 2016-07-04 15:50:33

Not work when <a> element have href address that set to http://????

@horse 2016-09-03 06:49:14

$('body').on('each', 'myclass', function() { // do something }); @Sean I tried to make something on "each" of a "class", but it doesn't work. What is wrong?

@Yusril Maulidan Raji 2017-06-19 08:44:41

in my case, it instead assigns the event on the parent tag. I use jquery version 1.12.4. Any idea?

@Sanjok Gurung 2018-08-16 10:37:39

Excellent solution, works well when adding DOM elements via javascript which were added during document.ready.

@Learner 2018-12-24 07:59:08

@Sean and Chuck, Thanks for the answer and the editing respectively. :)

@i-- 2013-03-29 03:09:06

You can bind a single click event to a page for all elements, no matter if they are already on that page or if they will arrive at some future time, like that:

$(document).bind('click', function (e) {
   var target = $(e.target);
   if (target.is('.myclass')) {
      e.preventDefault(); // if you want to cancel the event flow
      // do something
   } else if (target.is('.myotherclass')) {
      e.preventDefault();
      // do something else
   }
});

Been using it for a while. Works like a charm.

In jQuery 1.7 and later, it is recommended to use .on() in place of bind or any other event delegation method, but .bind() still works.

@ScottE 2009-08-31 19:39:27

If you're adding a pile of anchors to the DOM, look into event delegation instead.

Here's a simple example:

$('#somecontainer').click(function(e) {   
  var $target = $(e.target);   
  if ($target.hasClass("myclass")) {
    // do something
  }
});

@Matt Brunell 2009-08-31 19:30:58

After jQuery 1.7 the preferred methods are .on() and .off()

Sean's answer shows an example.

Now Deprecated:

Use the jQuery functions .live() and .die(). Available in jQuery 1.3.x

From the docs:

To display each paragraph's text in an alert box whenever it is clicked:

$("p").live("click", function(){
  alert( $(this).text() );
});

Also, the livequery plugin does this and has support for more events.

@frankadelic 2009-08-31 21:58:12

What if my selector needs to be the parent of some other element? For example: $("p").parent(".myclass").live("click", ... This doesn't seem to work with live().

@Matt Brunell 2009-09-01 01:41:41

You could try to incorporate that into a single query like $("p:has(.myclass)").live("click",...). Note: there are some cases where live doesn't work for all events. Check out livequery plugin for support not offered by live.

@Zach Lysobey 2012-02-17 15:47:56

This is no longer the correct Answer. The .live() method is deprecated as of jQuery 1.7. Use .on() instead. Lets get the correct answer[stackoverflow.com/a/9331127/363701] some upvotes. Or @Matt - do you want to update your answer?

@andres descalzo 2009-08-31 19:32:46

Binds a handler to an event (like click) for all current - and future - matched element. Can also bind custom events.

link text

$(function(){
    $(".myclass").live("click", function() {
        // do something
    });
});

@Francisco Corrales Morales 2014-05-12 22:41:13

live is deprecated.

@Adam Bellaire 2009-08-31 19:31:52

You want to use the live() function. See the docs.

For example:

$("#anchor1").live("click", function() {
    $("#anchor1").append('<a class="myclass" href="#">test4</a>');
});

@redsquare 2009-08-31 19:31:26

If your on jQuery 1.3+ then use .live()

Binds a handler to an event (like click) for all current - and future - matched element. Can also bind custom events.

Related Questions

Sponsored Content

61 Answered Questions

[SOLVED] How to check whether a checkbox is checked in jQuery?

77 Answered Questions

[SOLVED] How do I detect a click outside an element?

  • 2008-09-30 13:17:12
  • Sergio del Amo
  • 1109864 View
  • 2281 Score
  • 77 Answer
  • Tags:   javascript jquery

79 Answered Questions

[SOLVED] How do I remove a particular element from an array in JavaScript?

  • 2011-04-23 22:17:18
  • Walker
  • 5828943 View
  • 7266 Score
  • 79 Answer
  • Tags:   javascript arrays

29 Answered Questions

[SOLVED] jQuery scroll to element

  • 2011-07-13 09:49:44
  • DiegoP.
  • 2255636 View
  • 2116 Score
  • 29 Answer
  • Tags:   javascript jquery

54 Answered Questions

[SOLVED] How do I check if an element is hidden in jQuery?

34 Answered Questions

23 Answered Questions

[SOLVED] How can I refresh a page with jQuery?

23 Answered Questions

[SOLVED] Event binding on dynamically created elements?

11 Answered Questions

2 Answered Questions

[SOLVED] In Ext JS, how to attach events to dynamic html elements?

Sponsored Content