簡體   English   中英

屬性更改后,jQuery函數仍在運行

[英]JQuery function still running after attribute change

我的頁面上有一個菜單。 單擊每個菜單項時,它將調用以下功能之一:

$('.sideNav1').click(function(){
    $('.sideNav1').attr('class','selected1');
    $('.selected2').attr('class','sideNav2');
    $('.selected3').attr('class','sideNav3');
    alert("1 selected");
    return false;
});

$('.sideNav2').click(function(){
    $('.sideNav2').attr('class','selected2');
    $('.selected1').attr('class','sideNav1');
    $('.selected3').attr('class','sideNav3');
    alert("2 selected");
    return false;
});

$('.sideNav3').click(function(){
    $('.sideNav3').attr('class','selected3');
    $('.selected2').attr('class','sideNav2');
    $('.selected1').attr('class','sideNav1');
    alert("3 selected");
    return false;
});

HTML:

<div class="sideNav1">
Nav 1
</div>
<div class="sideNav2">
Nav 2
</div>
<div class="sideNav3">
Nav 3
</div>

更改屬性后(根據chrome中的開發工具確實發生了),我希望所選的div在單擊時不執行任何操作。 相反,它的行為就像沒有屬性更改一樣,並且仍然為.sideNav...調用click()事件偵聽.sideNav...再次運行該函數。

我這里可能缺少什么嗎?

jQuery靜態事件處理程序(您使用的類型)在首次運行代碼時將事件處理程序綁定一次。 之后對類名稱的任何更改都是無關緊要的,並且不會以任何方式影響事件處理程序。

對於傳播的事件,可以使用委托事件處理,該處理確實評估每個事件上的選擇器匹配。 在委派事件處理中,您將事件綁定到靜態父對象(安裝事件處理程序時其DOM元素存在,並且在任何時候都不會重新創建該對象的DOM元素),然后使用.on()的委派形式。

在您的情況下,您將必須選擇一個靜態父級的選擇器,並使用如下所示的內容:

$(some parent selector).on("click", ".sideNav1", function() {...});

盡管出於性能原因(在大頁面中),最好使用比<body>元素更近的父元素,但您甚至可以執行以下操作:

$(document.body).on("click", ".sideNav1", function() {...});

然后,僅當目標對象具有.sideNav1類名稱時才調用事件處理程序,否則將不調用該事件處理程序。

因此,委托事件處理的工作方式是:

  1. 某些事件(例如“ click”事件)會沿父鏈傳播。 在目標對象上調用它們之后,然后一直在鏈上的所有父對象上調用它們,一直到document對象,直到在其上調用.stopPropagation()為止。

  2. 因此,如果您在父對象上為特定事件安裝了事件處理程序,則可以看到所有發生在子對象上的事件(假設沒有人在子對象上調用.stopPropagation() )。

  3. 使用.on()的委托形式,jQuery將檢查父級調用的每個事件,以查看事件的原始目標與傳遞的第二個選擇器匹配,並在事件運行時檢查該事件。 因為此檢查在事件分發時是實時的,所以它會受到您對DOM元素進行的任何動態更改(如您的情況)的影響。

您可以在以下參考中閱讀有關委托事件處理的更多信息:

jQuery .live()vs .on()方法,用於在加載動態html后添加click事件

動態添加新元素后,jQuery選擇器不會更新

jQuery .on不起作用,但.live起作用

jQuery.on()是否可用於創建事件處理程序后添加的元素?

jQuery事件處理程序-什么是“最佳”方法

這些答案中最常見的情況是安裝事件處理程序后添加或重新創建的DOM元素,但問題與DOM元素幾乎相同,在DOM元素上您修改了它們的類並期望事件處理程序發生更改他們的行為。


僅供參考,我通常也建議您使用.addClass().removeClass()而不是.attr()因為這允許程序的其他部分在這些對象上使用其他類(出於樣式或其他原因)。

如果將sideNav類添加到所有div中,則可以執行以下操作:

$('.sideNav').click(function(){
    $('.sideNav').removeClass("selected");
    $(this).addClass("selected");

});

Jsfiddle示例: http : //jsfiddle.net/Tec3D/

好吧,我從現場轉為繼續...

   $(document).on('click','.sideNav1',function(){
    $(this).unbind('click').attr('class','selected1');
    $('.selected2').attr('class','sideNav2').bind('click');
    $('.selected3').attr('class','sideNav3').bind('click');
    alert("1 selected");
    return false;
});

$(document).on('click','.sideNav2',function(){
     $(this).unbind('click').attr('class','selected2');
    $('.selected1').attr('class','sideNav1').bind('click');
    $('.selected3').attr('class','sideNav3').bind('click');
    alert("2 selected");
    return false;
});

$(document).on('click','.sideNav3',function(){     
    $(this).unbind('click').attr('class','selected3');
    $('.selected2').attr('class','sideNav2').bind('click');
    $('.selected1').attr('class','sideNav1').bind('click');
    alert("3 selected");
    return false;
});

http://jsfiddle.net/BHL84/14/

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM