JQuery选择器误解了

时间:2013-12-04 02:19:45

标签: javascript jquery

我正在尝试创建一个简单的树视图脚本,并从打开/关闭节点开始。但我遇到了一些问题:

$(function() {

    $('#tree li.closedNode').on('click',function(e){
        e.stopPropagation();
        $(this).removeClass('closedNode').addClass('openedNode').children(':not(a.caption)').show();

    })  

    $('#tree li.openedNode').on('click',function(e){
        e.stopPropagation();

        $(this).addClass('closedNode').removeClass('openedNode').children(':not(a.caption)').hide();
    })

jsfiddle:http://jsfiddle.net/F33dS/14/

所以,然后你点击'点击这里'它关闭,改变类,但它仍然为'li.openedNode'发射事件。我知道,我错过了简单的事情,但是什么?我真的找不到问题。那么,为什么它以这种方式工作呢?

1 个答案:

答案 0 :(得分:2)

您将事件绑定到尚不存在的事物上。

您需要使用.on(),以便它定位所有匹配元素,无论它们现在还是将来都存在。

http://jsfiddle.net/F33dS/16/

$('#tree').on('click', 'li.closedNode', function(e){
    e.stopPropagation();
    $(this).removeClass('closedNode').addClass('openedNode').children(':not(a.caption)').show();
})  

$('#tree').on('click', 'li.openedNode', function(e){
    e.stopPropagation();
    $(this).addClass('closedNode').removeClass('openedNode').children(':not(a.caption)').hide();
})

您的节点在页面加载时具有类openNode

脚本查找$('#tree li.openNode')并匹配元素。

该脚本查找$('#tree li.closedNode')并且不匹配。

仅当用户点击该元素时,才会找到$('#tree li.closedNode')的匹配项。

因此,我们告诉其父存在哪个查找匹配后代的click事件。只要有一个MATCHING后代存在(当你更改类名时),事件就会触发。

来自http://api.jquery.com/on/

  

事件处理程序仅绑定到当前选定的元素;它们必须存在于您的代码调用.on()时的页面上。要确保元素存在且可以选择,请在文档就绪处理程序内对页面上HTML标记中的元素执行事件绑定。如果将新HTML注入页面,请在将新HTML放入页面后选择元素并附加事件处理程序。或者,使用委托事件来附加事件处理程序,如下所述。

     

委托事件的优势在于它们可以处理来自稍后添加到文档的后代元素的事件。通过选择在附加委托事件处理程序时保证存在的元素,您可以使用委派事件来避免频繁附加和删除事件处理程序的需要。

在原始代码中设置了正确的选择器,但当时没有匹配。因此,当时存在的#tree可以存储在其后代上创建的事件。

另外一件事

为什么用jQuery隐藏和显示列表元素?无论如何你要添加一个类,所以你可以用CSS做到这一点。

相关问题