最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - jQuery 'click' automatically fires 'live' - Stack Overflow

programmeradmin1浏览0评论

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.

发布评论

评论列表(0)

  1. 暂无评论