admin管理员组

文章数量:1379737

Here is a simple piece of code:

HTML:

<div id="close">Click me</div>

JS Code:

$("#close").click(function(){
    alert("1");
    $(this).attr('id','expand');
});



$("#expand").live('click', function(){
    alert("2");
    $(this).attr('id','close');            
});

Problem: When I click on "close" it automatically calls live() too. See this in jsfiddle: /

Is it because I am changing the same element's id from "close" to "expand"? How do I fix this problem?

I have tried:

 $("#expand").die().live('click', function()

but it didn't work. I tried event.stopPropagation() but that didn't help too. I tried having a separate div with id "expand" and hide it on document.ready but for some reason it is not working too.

Then I have tried since I read that live() has been deprecated in jQuery 1.7+:

$("#expand").on('click', function(){

and that is not working too.

Any thoughts? I think a fresh set of eyes will be able to spot what I am missing.

Thanks.

Here is a simple piece of code:

HTML:

<div id="close">Click me</div>

JS Code:

$("#close").click(function(){
    alert("1");
    $(this).attr('id','expand');
});



$("#expand").live('click', function(){
    alert("2");
    $(this).attr('id','close');            
});

Problem: When I click on "close" it automatically calls live() too. See this in jsfiddle: http://jsfiddle/uFJkg/

Is it because I am changing the same element's id from "close" to "expand"? How do I fix this problem?

I have tried:

 $("#expand").die().live('click', function()

but it didn't work. I tried event.stopPropagation() but that didn't help too. I tried having a separate div with id "expand" and hide it on document.ready but for some reason it is not working too.

Then I have tried since I read that live() has been deprecated in jQuery 1.7+:

$("#expand").on('click', function(){

and that is not working too.

Any thoughts? I think a fresh set of eyes will be able to spot what I am missing.

Thanks.

Share Improve this question asked Aug 16, 2012 at 19:38 BlueboyeBlueboye 1,4944 gold badges27 silver badges54 bronze badges 3
  • What happens if you return true; from your first click function? – Platinum Azure Commented Aug 16, 2012 at 19:40
  • You're adding two handlers for the same event, yes? – Brad Commented Aug 16, 2012 at 19:40
  • Yeah but I am changing the id of the div. Wouldn't that be considered as a different event then? @Platinum: I am using the on() instead of live() and it is not even being called now. – Blueboye Commented Aug 16, 2012 at 19:42
Add a ment  | 

3 Answers 3

Reset to default 10

You need both delegate event (aka live) handler in this case. Because, you're toggling between both ids and this toggling make both ids as dynamic to DOM.

$("body").on("click", "#close", function(){
    alert("1");
    $(this).attr('id','expand');
});

$("body").on("click", "#expand", function(){
    alert("2");
    $(this).attr('id','close');            
});

DEMO

Note

As live() is deprecated, so instead of live() use .on() for delegate event handling.

This has to do with the way live attaches events and how event bubbling works.

.live attaches event handlers to the document. When the document registers an event, it looks to see what the target of that event is. If it matches the selector passed to .live, it fires the handler.

So, when you click on #close, this is what happens:

  1. click event registered on #close, handler fires.
  2. #close is changed to #expand
  3. click event bubbles up the DOM until it reaches the document
  4. click event registers on document, document sees that the ID of the target element is #expand, and it fires the event handler

The way to solve this is to add stopPropagation() to your handlers:

$("#close").click(function(e){
  if(!e) { e = window.event; }
  e.stopPropagation();

  alert("1");
  $(this).attr('id','expand');
});

However, I would remend not using live and looking into delegate or on to handle delegated events.

I would also remend against changing the ID. I would try something like this if you want to keep the close/expand idea:

<div id="toggler" class="close">Close</div>

$('#toggler').on('click',function() {
    $(this).toggleClass('close').toggleClass('expand');
});

One event handler, no delegation because it hooks into the permanent ID

First of all, it's not very clean to change your id's runtime. You're facing one of the results of that.

You might consider using the data-attributes. jQuery can read them by accessing the data property.

Eg.

$("#myObject").data("expanded", true);

In that way it's not necessary to change your id's.

本文标签: javascriptjQuery 39click39 automatically fires 39live39Stack Overflow