给出以下标记:
<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);
}
首先,它似乎工作得很好,只要我点击原始节点。例如,如果我点击“蓝色”,我会得到:
<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>
然而,当我点击新节点时,不是将新节点作为兄弟节点,而是向上一级(即,'Colors','Size'和'Material'的兄弟)。看看jQuery生成的标记,我没有看到任何区别,所以我很难过为什么新节点的行为与原始节点不同。感谢。
答案 0 :(得分:2)
我建议:
$("#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
元素,而不是this
它使用e.target
,这是ul
中单击的元素。这意味着您可以避免将click事件处理程序绑定到新添加的元素的问题。
答案 1 :(得分:0)
原因是jquery将您的点击回调注册到现有对象。当你点击新创建的li时,它会冒泡并向上发射一级。
除此之外:你有class =“nodes”,你想拥有id =“nodes”。
如何解决这个问题?尝试将您的点击注册到ul(不是li),然后在addSibling中删除parent。
答案 2 :(得分:0)
因为当你向DOM添加一个新节点时,你没有附加一个click事件,所以底层的'li'正在注册click并将节点附加到该节点。要解决此问题,请在addSibling函数中创建新节点后,将click事件附加到该节点。
答案 3 :(得分:0)
您的问题是您新创建的<li>
没有附加事件处理程序。那是因为当你调用$("#nodes ul li").click(...)
时,只有符合选择器的元素才能将处理程序附加到它们上面。调用该函数后,当新元素添加到DOM时,不会再次调用它。因此,您点击新的<li>
s会“冒泡”,直到它遇到已有事件处理程序的<li>
。
您可以通过使用委托点击处理程序来解决此问题,而不是直接在元素上使用:
$("#nodes").on("click","li",function(e) {
addSibling(this, 'new one');
e.stopPropagation();
});
其工作方式如下:
您只将一个单击处理程序附加到#nodes
元素。当您单击<li>
元素内的任何nodes
时,该函数将被触发。由于它适用于<li>
元素内的所有#nodes
,因此动态创建它们并不重要。