previousSibling在控制台中显示了两个不同的东西

时间:2015-10-02 17:06:13

标签: javascript html

我正在尝试使用按钮将列表中的li移动到列表中。我正在使用控制台跟踪某些变量,以查看我的代码是否正常运行。我在观看控制台时发现了一些非常好奇的东西。

当我点击列表中某个项目的向上箭头时,变量itemBefore显示" #text" (对象)在控制台中。此外,列表项不会像它应该的那样移动。它保持不变。

现在我再次单击同一列表项上的按钮,控制台显示li,列表项确实向上移动。它为每个不是第一个的列表项执行此操作(因为它将在if语句中执行另一个代码子集)。

我想知道为什么完全相同的onclick做了两件不同的事情以及如何阻止它第一次失败。

<ul id="incomplete-tasks">
    <li>
        <button class="arrow up">&#8593;</button>
        <button class="arrow down">&#8595;</button>
        <label>Item 1</label>
        <input type="text">
        <button class="edit">Edit</button>
        <button class="delete">Delete</button>
    </li>
    <li>
        <button class="arrow up">&#8593;</button>
        <button class="arrow down">&#8595;</button>
        <label>Item 2</label>
        <input type="text">
        <button class="edit">Edit</button>
        <button class="delete">Delete</button>
    </li>
    <li>
        <button class="arrow up">&#8593;</button>
        <button class="arrow down">&#8595;</button>
        <label>Item 3</label>
        <input type="text">
        <button class="edit">Edit</button>
        <button class="delete">Delete</button>
    </li>
</ul>

JavaScript:

var moveUp = function() {
    var listItem = this.parentNode;
    var ul = listItem.parentNode;
    var items = ul.getElementsByTagName("li");
    var arr = [].slice.call(items);
    var position = arr.indexOf(listItem);
    console.log(position);
    if (position < 1) {
        var removedChild = ul.removeChild(listItem);
        ul.appendChild(removedChild);
    } else {
        var itemBefore = listItem.previousSibling;
        console.log(itemBefore);
        var removedChild = ul.removeChild(listItem);
        ul.insertBefore(removedChild, itemBefore);
    }
};

如果你想/需要查看整个代码来演示错误,那么jsfiddle是链接的:

https://jsfiddle.net/09yyfxae/

2 个答案:

答案 0 :(得分:2)

你正在捕捉空白。如果您编辑标记以将其删除,例如

<ul id="incomplete-tasks"><li>
    <button class="arrow up">&#8593;</button>
    <button class="arrow down">&#8595;</button>
    <label>Item 1</label>
    <input type="text">
    <button class="edit">Edit</button>
    <button class="delete">Delete</button>
</li><li>
    <button class="arrow up">&#8593;</button>
    <button class="arrow down">&#8595;</button>
    <label>Item 2</label>
    <input type="text">
    <button class="edit">Edit</button>
<button class="delete">Delete</button>
</li><li>
    <button class="arrow up">&#8593;</button>
    <button class="arrow down">&#8595;</button>
    <label>Item 3</label>
    <input type="text">
    <button class="edit">Edit</button>
    <button class="delete">Delete</button>
    </li>
</ul>

每次都会获得正确的项目:https://jsfiddle.net/09yyfxae/1/

或者(并且最好)只是在遇到代码时跳过代码中的空格并执行另一个兄弟查找,例如:

var itemBefore = listItem.previousSibling;
while (itemBefore.nodeName == '#text') itemBefore = itemBefore.previousSibling;

答案 1 :(得分:0)

这是因为您的结束</li>和下一个开始<li>标记之间的空格会创建文本节点(因此第一个调试输出会显示#text)。

因此,在第一次点击时,您将li移到其前面的文本节点之前 - 并且只有在下一次点击时才会在下一个li之前移动它。

https://developer.mozilla.org/en-US/docs/Web/API/Node/previousSibling