0

I have, for example this:

$first = $('#firstElement').click(function() { });

But in some point of the execution of the page, I will replace that element with another:

$newElement = jQuery('<div />');
$first.replaceWith($newElement);

But I want to keep the callbacks for the first element in the second...

Is that possible?

EDIT 1

I already know how to do it with .on() or .delegate(). This is my scenario:

I need to load something once a selector change, however, the content of that selector will vary according to the role of the logged-in user. I already have the information stored in localstorage. The content of that selector is loaded via:

window.Core.setBranchesSelector($('#theElementInWhichTheSelectorWillBe'));

That function create a <select> element. I can make within the js for that page:

$('#parent').on('click', '#theElementInWhichTheSelectorWillBe', function() {});

But I wanted to make that function as flexible as possible, thus, if I make somethink like:

$elementToBeReplaced = $('<coolElement />').click(function() {});
/* Something really cool with that element */
Core.setBranchesSelector($elementToBeReplaced);

The selector inherit the callback for the click event...

Cito
  • 1,659
  • 3
  • 22
  • 49
  • 3
    I suggest you use event delegation and avoid that scenario. – Nelson Mar 29 '13 at 17:38
  • I already know how to do it with .on() or with .delegate(), but I wanted to do it in that way... Thanks for you suggestion anyways :) – Cito Mar 29 '13 at 19:06

3 Answers3

2

The plain answer to your question: No, you can not do it. At least not in the new versions of jQuery (with 1.7 you can do it, as @undefined already states in the comments to the answer #15708467).

However, here's a simple example using delegation with .on():

http://jsfiddle.net/8dCQT/

$(function() {
    $("#parent").on("click", ".child", function() {
        alert($(this).text());
    });
    $("input").click(function() {
        $(".child").remove();
        $("#parent").append("<div class='child'>I'm a replacement</div>");
    });
});

You'll notice after clicking the button, clicking the replacement div calls the same click function and alerts with the text of the new div.

Note: the important part here is that the replacement be selectable with the same selector (in this case .child) as the original. I used a class here, but I could have used first child of the parent, or whatever else works.

Also note: You don't have to bind to an immediate parent either, you can bind all the way at the top with document, but that's not recommended because it will slow down your code. You should bind as close to the elements you want to attach events to as possible so the code won't have to walk too far down the DOM tree.

Cito
  • 1,659
  • 3
  • 22
  • 49
Matt Burland
  • 44,552
  • 18
  • 99
  • 171
  • I choosed this as the answer cause it explains how will work. Also, I've added the real answer to my question: No, you cannot do it. Thanks to everyone :) – Cito Mar 29 '13 at 19:42
1

jQuery does not provide an API to directly access already bound events.

Place the event on a parent element, replace the child element, and depend on event bubbling to catch it.

Joseph Lennox
  • 3,202
  • 1
  • 27
  • 25
  • That's not true, `data('events')`. – Ram Mar 29 '13 at 17:45
  • @undefined So with that I could get the callback and assigned to another one? – Cito Mar 29 '13 at 19:05
  • @AbrahamSustaita If you are using jQuery 1.7, yes, http://stackoverflow.com/questions/10222143/copying-event-handlers-from-one-set-of-elements-to-another-one-using-jquery – Ram Mar 29 '13 at 19:07
  • @undefined The jQuery team has intentionally removed that undocumented way of getting events. I do not agree with their actions, but it's been that way for a while. You should not promote people to use undocumented APIs as the chances of it breaking in the future (in this case, _the past_) is very real. – Joseph Lennox Mar 29 '13 at 20:53
1

You'll either need to include the same id in each element or give each div a common class. Once you do that, it's as easy as:

$(document).on('click','.some-common-class',function(){
});
Justin Niessner
  • 242,243
  • 40
  • 408
  • 536
  • 1
    You should never bind to the document like that. It creates very difficult to manage code and ultimately degrades performance. – Joseph Lennox Mar 29 '13 at 17:43
  • @JosephLennox - I would agree, but not knowing the structure of the document...this is the best alternative (the direct translation of what used to be `$('.some-common-class').live()`). – Justin Niessner Mar 29 '13 at 17:44