1

Suppose I have the following code:

<div id="outerrt">
  <div id="rt" style="width: 200px; height: 200px; border: 1px solid black;">
    <span id="rt2">content</span>
  </div>
</div>

And I use the following:

$("#outerrt *").live("click", function () {
  alert($(this).attr('id'));
});

What it would give me when I click on the content text is three alert windows, in the following order:

rt2

rt

outerrt

What I actually want it to give me is only one id: rt2. How do I accomplish that?

Lucas
  • 16,930
  • 31
  • 110
  • 182
  • @SnakeEyes But does `on` automatically accept newly created elements of the same circumstances? – Lucas Sep 01 '12 at 09:31
  • Then use `delegate` as mentioned in below answers from different users. See @undefined answer – Snake Eyes Sep 01 '12 at 09:36
  • yes, events will bubble up the DOM tree until it reaches #outerrt. `live`, `delegate` and `on` will all trigger. `delegate` and `on` then check if the event started on something matching their more specific selector to decide whether to call the event handler. Newly created elements lower in the hierarchy still trigger at the #outerrt level. – ronalchn Sep 01 '12 at 09:36

5 Answers5

1

Is this what you want?

$("#rt2").live("click", function () {
  alert($(this).attr('id'));
});
Littm
  • 4,923
  • 4
  • 30
  • 38
  • sorry it isn't, as the content for `rt` is constantly changing, and may not even contain the `rt2` element. – Lucas Sep 01 '12 at 09:33
  • I think what you can do I think is to apply the live click event to **$("rt .your_added_obj")** and to make sure to add the class **"your_added_obj"** to the object you will add. – Littm Sep 01 '12 at 09:37
  • The OP says it needs to work with newly created objects, in which case binding directly to the object isn't appropriate. – ronalchn Sep 01 '12 at 09:40
1
$('#outerrt').on( 'click', '#rt', function() {
  alert($(this).attr('id'));
});

edit: $(this) works just as well as $(e.target)

Austin Greco
  • 32,997
  • 6
  • 55
  • 59
1

You can use target property of the event object.

$(document).on("click", '#outerrt', function(event) {
      alert(event.target.id);
      // $(event.target).attr('id')
});
Ram
  • 143,282
  • 16
  • 168
  • 197
  • you shouldn't bind on document if you have a much closer element you can bind to – Austin Greco Sep 01 '12 at 09:35
  • @agreco It seems that _event delegation_ is not necessary here. How do you know that `outerrt` is a static element? – Ram Sep 01 '12 at 09:38
  • This doesn't seem to be 100% jQuery. Can you make it like that? – Lucas Sep 01 '12 at 09:40
  • the OP binded `live` on #outerrt, so I think we can assume that this element is static, even if its contents are not. – ronalchn Sep 01 '12 at 09:41
  • @ronalchn: The `live` method always binds the event at document level, so it's not certain that any element in the selector exists at that time. – Guffa Sep 01 '12 at 09:43
  • @think123 jQuery is JavaScript, what do you mean by 100% jQuery? I have updated the code. – Ram Sep 01 '12 at 09:47
  • yep that's what i mean. Thank you. – Lucas Sep 01 '12 at 10:32
1

Actually it would only give you the first two alerts, as the #outerrt * selector doesn't match the element with id="outerrt".

To stop the event from bubbling, use the stopPropagation method:

$("#outerrt *").live("click", function (e) {
  e.stopPropagation();
  alert($(this).attr('id'));
});

In newer versions of jQuery the live and delegate methods are deprecated, and they have crammed all that functionality into the on method, so the equivalent code would be:

$("body").on("click", "#outerrt *", function (e) {
  e.stopPropagation();
  alert($(this).attr('id'));
});

However, you should put the delegate as close as possible to the elements where you want to catch the event, i.e. on the element where you will be loading the content. Example:

$("#outerrt").on("click", "*", function (e) {
  e.stopPropagation();
  alert($(this).attr('id'));
});
Guffa
  • 687,336
  • 108
  • 737
  • 1,005
0

Either bind it directly on #rt2, or use delegate or on instead (depending on your jQuery version).

Using delegate, you can pass a more specific selector:

$("#outerrt *").delegate("span","click", function () {
  alert($(this).attr('id'));
});

Similarly with on:

$("#outerrt").on("click", "#rt2", function(event){
  alert($(this).attr('id'));
});

In either case the more specific selector (span or #rt2) means that it only triggers if the click occurs on something matching that selector.

ronalchn
  • 12,225
  • 10
  • 51
  • 61
  • When you say `depending on your jQuery version`, I've got the latest (1.8.0). Can you tell me what to use for this specific version? Thanks. – Lucas Sep 01 '12 at 09:31
  • Use `on`. As of jQuery 1.7, `on` supersedes `delegate`. This means `delegate` is likely to be deprecated and removed in the future. – ronalchn Sep 01 '12 at 09:33
  • @think123 .live() is deprecated, you should use .on(). More information found here: http://stackoverflow.com/questions/8359085/delegate-vs-on – 11684 Sep 01 '12 at 09:38