Недавно я начал изучать javascript и на данный момент пытаюсь создать простое приложение, то есть ul, с элементами списка, где у каждого 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>
Вот jsfiddle: https://jsfiddle.net/hu13x8w0/3/
Может кто-нибудь объяснить мне, почему это не работает в этих двух случаях? Что я сделал не так?
Если вы проверите консоль браузера (F12, чтобы открыть Dev Tools в большинстве браузеров), вы увидите такую ошибку:
Uncaught TypeError: Cannot read property 'nextElementSibling' of null
Это потому, что на этой линии:
li.nextElementSibling.nextElementSibling;
... последний элемент .nextSibling
имеет значение null
(у него нет следующего брата). Вам нужно проверить значение null
а не просто .nextElementSibling
дополнительный .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()
перемещает элемент (не копирует его).
Move Up
в верхнем ряду.