向上和向下移动列表项的Javascript问题

时间:2017-06-30 15:35:14

标签: javascript events

最近开始学习javascript,我现在正在尝试构建一个简单的应用程序,这是一个带有列表项的ul,其中每个li有两个按钮,用于向上或向下移动li。

但是,我遇到了问题。列表中的最后一项永远不能上移



    var ul = document.querySelector('ul');
    
    ul.addEventListener('click', (e) => {
    	let clicked = e.target;
    	let li		= clicked.parentNode;
    	let next    = li.nextElementSibling.nextElementSibling;    
     	let prev    = li.previousElementSibling;
        
        if (clicked.className === 'down') {
        	ul.removeChild(li);
            ul.insertBefore(li, next);
        } else if (clicked.className === 'up') {
        	ul.removeChild(li);
        	ul.insertBefore(li, prev);
        }
    });

    <ul>
        <li>item1 <button class="down">Move down</button><button class="up">Move up</button></li>
        <li>item2 <button class="down">Move down</button><button class="up">Move up</button></li>
        <li>item3 <button class="down">Move down</button><button class="up">Move up</button></li>
        <li>item4 <button class="down">Move down</button><button class="up">Move up</button></li>
        <li>item5 <button class="down">Move down</button><button class="up">Move up</button></li>
    </ul>
&#13;
&#13;
&#13;

这是jsfiddle:https://jsfiddle.net/hu13x8w0/3/

有人可以向我解释,为什么它不会在这两种情况下起作用?我做错了什么?

1 个答案:

答案 0 :(得分:2)

如果您检查浏览器的控制台(F12在大多数浏览器中打开Dev Tools),您会看到如下错误:

Uncaught TypeError: Cannot read property 'nextElementSibling' of null

那是因为在这一行:

li.nextElementSibling.nextElementSibling;

...最后一个元素的.nextSiblingnull(它没有下一个兄弟)。您需要测试null,而不是仅仅在最后链接一个额外的.nextElementSibling

    var ul = document.querySelector('ul');
    
    ul.addEventListener('click', (e) => {
    	let clicked = e.target;
    	let li		= clicked.parentNode;
    	let next    = li.nextElementSibling;               // <-- Code changed
        if (next != null) next = next.nextElementSibling;  // <-- Code inserted
     	let prev    = li.previousElementSibling;
        
        if (clicked.className === 'down') {
        	ul.insertBefore(li, next);
        } else if (clicked.className === 'up') {
        	ul.insertBefore(li, prev);
        }
    });
    <ul>
        <li>item1 <button class="down">Move down</button><button class="up">Move up</button></li>
        <li>item2 <button class="down">Move down</button><button class="up">Move up</button></li>
        <li>item3 <button class="down">Move down</button><button class="up">Move up</button></li>
        <li>item4 <button class="down">Move down</button><button class="up">Move up</button></li>
        <li>item5 <button class="down">Move down</button><button class="up">Move up</button></li>
    </ul>

请注意,您不需要拨打.removeChild(),因为.insertBefore() 移动元素(不会复制)。