Javascript JQuery选择器理解错误

Javascript JQuery选择器理解错误,javascript,jquery,Javascript,Jquery,我正在尝试制作一个简单的树视图脚本,并从打开/关闭节点开始。但我遇到了一些问题: $(function() { $('#tree li.closedNode').on('click',function(e){ e.stopPropagation(); $(this).removeClass('closedNode').addClass('openedNode').children(':not(a.caption)').show(); })

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

$(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:


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

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

您需要使用.on,以便它针对所有匹配的元素,无论它们现在或将来是否存在

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

脚本查找$'tree li.openNode'并匹配元素

脚本将查找$'tree li.closedNode',但不匹配

只有当用户单击元素时,才会找到$'tree li.closedNode'的匹配项

因此,我们告诉它的父对象(存在)为两个匹配的子对象查找click事件。当您更改类名时,只要有一个匹配的子体出现,事件就会触发

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

委派事件的优点是,它们可以处理来自子元素的事件,这些子元素将在以后添加到文档中。通过选择在附加委派事件处理程序时保证存在的元素,可以使用委派事件来避免频繁附加和删除事件处理程序

在原始代码中设置了正确的选择器,但当时没有匹配项。因此,当时存在的树可以存储在其子代上发生的事件

还有一件事


为什么要用jQuery隐藏和显示列表元素?无论如何,您都在添加一个类,这样您就可以使用CSS来实现这一点。

您是否曾经在不使用jQuery的情况下将事件处理程序绑定到元素?如果是这样的话,你用的时候也是一样的。元素被选中,函数被绑定到元素。如果不是的话,最好是有一些将处理程序绑定到本机元素的经验。哦,我考虑过了,但我调用了脚本,然后加载了页面,html已经存在了,我想是的。我很困惑。不管怎样,谢谢。好的,我会解释的。HTML存在。您的节点在页面加载时具有openNode类。您查找$'tree li.openNode'-它们存在。您查找$tree li.closedNode'-没有。它们只在用户交互之后才存在。到那时,$tree li.closedNode'已经出现了。它不会再检查了。好吧,现在我明白了,再一次谢谢你,还有css的想法。我总是忘了我,太好了。为了以防万一,我更新了我的答案,增加了一个较长的解释。
$('#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();
})