我正在尝试使用按钮将列表中的li移动到列表中。我正在使用控制台跟踪某些变量,以查看我的代码是否正常运行。我在观看控制台时发现了一些非常好奇的东西。
当我点击列表中某个项目的向上箭头时,变量itemBefore显示" #text" (对象)在控制台中。此外,列表项不会像它应该的那样移动。它保持不变。
现在我再次单击同一列表项上的按钮,控制台显示li,列表项确实向上移动。它为每个不是第一个的列表项执行此操作(因为它将在if语句中执行另一个代码子集)。
我想知道为什么完全相同的onclick做了两件不同的事情以及如何阻止它第一次失败。
<ul id="incomplete-tasks">
<li>
<button class="arrow up">↑</button>
<button class="arrow down">↓</button>
<label>Item 1</label>
<input type="text">
<button class="edit">Edit</button>
<button class="delete">Delete</button>
</li>
<li>
<button class="arrow up">↑</button>
<button class="arrow down">↓</button>
<label>Item 2</label>
<input type="text">
<button class="edit">Edit</button>
<button class="delete">Delete</button>
</li>
<li>
<button class="arrow up">↑</button>
<button class="arrow down">↓</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是链接的:
答案 0 :(得分:2)
你正在捕捉空白。如果您编辑标记以将其删除,例如
<ul id="incomplete-tasks"><li>
<button class="arrow up">↑</button>
<button class="arrow down">↓</button>
<label>Item 1</label>
<input type="text">
<button class="edit">Edit</button>
<button class="delete">Delete</button>
</li><li>
<button class="arrow up">↑</button>
<button class="arrow down">↓</button>
<label>Item 2</label>
<input type="text">
<button class="edit">Edit</button>
<button class="delete">Delete</button>
</li><li>
<button class="arrow up">↑</button>
<button class="arrow down">↓</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