2015-10-02 6 views
0

Я пытаюсь использовать кнопку для перемещения li в ul вверх по списку. Я использую консоль для отслеживания определенных переменных, чтобы проверить, работает ли мой код правильно. Я нашел что-то очень любопытное, наблюдая за консолью.previousSibling показывает две разные вещи в консоли

Когда я нажимаю стрелку вверх для элемента в списке, переменная itemBefore показывает «#text» (объект) в консоли. Кроме того, элемент списка не перемещается так, как предполагается. Он остается на месте.

Теперь я снова нажимаю кнопку в том же элементе списка, вместо этого консоль показывает ли, и элемент списка действительно перемещается вверх. Он делает это для каждого элемента списка, который не является первым (потому что это приведет к выполнению другого подмножества кода в инструкции 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

Вы» повторное захват пробелов. Если вы отредактируете свою разметку, чтобы удалить ее, например.

<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; 
+0

Как пропустить пробел в коде? Подумав об этом, я мог бы запустить цикл while, пока переменная «whitespace» выполняет другой поиск по сестре. Но как я представляю пробелы в JavaScript? –

+0

@JohnCoolidge Вы можете просто наблюдать за текстовым узлом, что-то вроде строк: 'while (itemBefore.nodeName == '#text') itemBefore = itemBefore.previousSibling;' проверено здесь: https://jsfiddle.net/09yyfxae/ 3/ –

+0

Отлично! Спасибо! :) –

0

Это связано с тем, что пробелы между вашими замыканиями </li> и последующими открытиями <li> теги создают текстовые узлы (отсюда первый вывод отладки #text).

Итак, при первом нажатии вы перемещаете свой li перед тем, как он предшествует текстовому узлу, и только при следующем нажатии вы на самом деле перемещаете его до следующего li.

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

+0

Ах, просмотрев заметки на MDN для предыдущего сеанса, он говорит именно об этом. В примерах, которые они использовали, не было братьев и сестер на следующей строке, таким образом, не было пробелов. Есть ли свойство, как предыдущий брат, который игнорирует пустое пространство, или я просто застрял с каким-то загроможденным HTML? –

Смежные вопросы