1

I am experiencing some weird behavior in jQuery (v1.7):

I am trying to set an event listener to an element that actually gets replaced at some point via ajax.

$(document.getElementById('element')).live('click', function() {
    // do something on click
});

while this works fine with other methods, the live method refuses to run. when replacing this with the native jQuery selector it works. Why?

$("#element").live('click', function() {
    // do something on click
}); 
Erik Pöhler
  • 742
  • 2
  • 9
  • 22

6 Answers6

3

live doesn't work this way. The event bubbles up to the document and then the target of the event is examined to see if it matches the selector.

It's likely that the element you're listening for events on does not exist when you bind the event handler, so getElementById returns nothing.

When you think about the semantics of live it doesn't make sense to pass it a DOM element.

Andrew Whitaker
  • 124,656
  • 32
  • 289
  • 307
  • Actually the resulting `jQuery` object does not contain selector in the first case (when you use `getElementById`), because it does not know about it (because it gets already selected raw DOM object), while in the second case the selector is saved within the jQuery object (it does not matter here, if anything was matched when the `.live()` was set). This is one of the reasons, why one should not use `.live()`, and instead replace it with `.on()` (since jQuery 1.7) or `.delegate()` (earlier than jQuery 1.7). Anyway, +1 for mentioning how `.live()` works. – Tadeck Aug 14 '12 at 23:41
2

document.getElementById is grabbing an element that currently exists. When you pass a string, "#id", with live, jQuery is looking for events in the future on document.body that originate from an element with an ID matching that string.

As a side note, look into .on() as .live() is not only computationally expensive, but deprecated.

Stephen
  • 5,710
  • 1
  • 24
  • 32
1

I'm fairly sure that in the first case you are passing a simple node to the jQuery constructor, which means that as soon as that node is gone the object won't refer to anything anymore and so live cannot work.

On the other hand, by passing it the jQuery selector instead, live can constantly look for the element with that ID even if it is removed, re-added or otherwise kicked around.

Niet the Dark Absol
  • 320,036
  • 81
  • 464
  • 592
1

.live() filters all click events to see which ones match the selector that you created the jQuery object from.
It has nothing to do with the elements currently in the jQuery object.

Writing $(element).live() will not do anything, since there is no selector.

SLaks
  • 868,454
  • 176
  • 1,908
  • 1,964
1

Because live will attach the actual event to the document, which is called delegation.

Then when a click happens, jQuery checks if the element in the selector was the origin of the event and if it is, your function gets called.

While $("#element") can see if there is an element matching the selector, $(document.getElementById("element)); can not, because there is no selector, just an object, which is missing after you remove it.

Torsten Walter
  • 5,614
  • 23
  • 26
  • 1
    +1 for probably the best explanation so far. `$("#element")`'s result is a jQuery object, which also stores the selector used for creating it. So even if no elements were matched, jQuery object contains information on how to find them in the future (which is then used by `.live()` for checking `event.target`). – Tadeck Aug 14 '12 at 23:45
0

The native JavaScript getElementById gives you the actual DOM object whereas the jquery selector gives you a jquery wrapper around object(s).

.live needs a jquery wrapper to work I think.

Also you should use .on or .delegate as .live has been deprecated as of 1.7

Moin Zaman
  • 25,281
  • 6
  • 70
  • 74