将兄弟节点添加到嵌套列表

时间:2013-04-20 21:05:34

标签: 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></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生成的标记,我没有看到任何区别,所以我很难过为什么新节点的行为与原始节点不同。感谢。

4 个答案:

答案 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);
}

JS Fiddle demo

这会将点击处理程序绑定到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,因此动态创建它们并不重要。