繁体   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