Javascript 将同级节点添加到嵌套列表
给定以下标记:Javascript 将同级节点添加到嵌套列表,javascript,jquery,html-lists,Javascript,Jquery,Html Lists,给定以下标记: <div id="nodes"> <ul> <li><a href="#">Colors</a> <ul> <li><a href="#">Red</a></li> <li><a href="#">Green</a>
<div id="nodes">
<ul>
<li><a href="#">Colors</a>
<ul>
<li><a href="#">Red</a></li>
<li><a href="#">Green</a></li>
<li><a href="#">Blue</a></li>
</ul>
</li>
<li><a href="#">Sizes</a></li>
<li><a href="#">Material</a></li>
</ul>
</div>
-
我编写了一个jQuery函数来添加同级节点:
$("#nodes ul li").click(function(e) {
addSibling(this, 'new one');
e.stopPropagation();
});
function addSibling(selector, content){
var markup='<li><a href="#">' + content + '</a></li>';
$(selector).parent().append(markup);
}
$(“#节点ul li”)。单击(函数(e){
addSibling(这个“新的”);
e、 停止传播();
});
函数addSibling(选择器、内容){
变量标记=“”;
$(选择器).parent().append(标记);
}
一开始,只要我单击原始节点,它似乎工作得很好。例如,如果我单击“蓝色”,我会得到:
<div id="nodes">
<ul>
<li><a href="#">Colors</a>
<ul>
<li><a href="#">Red</a></li>
<li><a href="#">Green</a></li>
<li><a href="#">Blue</a></li>
<li><a href="#">new node</a></li>
</ul>
</li>
<li><a href="#">Sizes</a></li>
<li><a href="#">Material</a></li>
</ul>
</div>
-
但是,当我单击新节点时,它不是将新节点作为同级节点,而是向上一级(即“颜色”、“大小”和“材质”同级节点)。查看jQuery生成的标记,我看不出有什么区别,所以我很困惑为什么新节点的行为不同于原始节点。谢谢。原因是jquery将您的单击回调注册到已有的对象。当你点击新创建的li时,它只会冒出气泡并触发一个更高的级别 除此之外:您有class=“nodes”,并且希望有id=“nodes”
如何解决这个问题?尝试注册单击到ul(而不是li)并在addSibling中删除父节点。因为当您将新节点添加到DOM时,您没有将单击事件附加到DOM,所以基础“li”正在注册单击并将节点附加到该DOM。要解决此问题,请在addSibling函数中,在创建新节点后,向其附加一个click事件。您的问题是新创建的
没有附加事件处理程序。这是因为当您调用$(“#nodes ul li”)。单击(…)
只有适合选择器的元素才能附加处理程序。一旦调用了该函数,当向DOM中添加新元素时,将不会再次调用该函数。因此,单击new
s“冒泡”,直到它遇到一个已经有事件处理程序的
您可以通过使用委托单击处理程序而不是直接在元素上使用委托单击处理程序来解决此问题:
$("#nodes").on("click","li",function(e) {
addSibling(this, 'new one');
e.stopPropagation();
});
其工作方式如下:只能将一个单击处理程序附加到
#节点
元素。当您单击节点
元素内的任何
时,将触发该函数。由于它适用于#nodes
元素中的所有,因此动态创建它们并不重要。我建议:
$("#nodes ul").click(function (e) {
addSibling(e.target, 'new one');
e.stopPropagation();
});
function addSibling(selector, content) {
var markup = '<li><a href="#">' + content + '</a></li>';
$(selector).parent().append(markup);
}
$(“#节点ul”)。单击(函数(e){
addSibling(例如,target,“newone”);
e、 停止传播();
});
函数addSibling(选择器、内容){
变量标记=“”;
$(选择器).parent().append(标记);
}
这会将单击处理程序绑定到ul
元素,并使用e.target
,而不是This
,后者是在ul
中单击的元素。这意味着您可以避免没有将单击事件处理程序绑定到新添加的元素的问题。感谢复制粘贴解决方案,但由于某些原因,它无法工作。这可能是因为我复制了您的JS。。。在JS中使用id
,而在HTML中使用类。因此,要么将JS更改为$(“.nodes”)
,要么将HTML更改为id=“nodes”
我在代码中编辑了选择器以匹配我的标记,但它仍然不起作用。无论如何,谢谢。对不起,我刚意识到我把参数弄错了。。。哎呀。。。上面的代码现在是正确的。(之前,“click”
和“li”
是反向的)我去试过了,但例如,单击“Red”,会给你两个新节点,而不是一个。