2016-04-01 4 views
1

Я хочу изменить порядок элементов NodeList, например, переместить узел1 после узла2. Коды, являются следующие:Как применить функцию сращивания к массиву NodeList?

var cols = document.querySelectorAll("ul>li"); 
var target = cols[0]; 
[].splice.call(cols,[0, 1]); 
[].splice.call(cols,[3, 0, target]); 

Но он бросает исключение:

Uncaught TypeError: Cannot set property length of # which has only a getter

Означает ли это, не может применить функцию сплайсинга для NodeList массива?

+0

связаны, если не дублировать: [Использовать функции массива Prototype с не-массивов] (http://stackoverflow.com/q/36026931/1048572) – Bergi

ответ

2

Does it mean cannot apply splice function to NodeList array?

Да, это так, потому что в NodeList isn't an array, but an array-like object. Array.prototype.function.apply(someNodeList) работает в случаях, которые не мутируют NodeList.


Если ваша цель состоит в том, чтобы изменить порядок элементов, вы должны учитывать, что вам придется манипулировать DOM другим способом - не через эту NodeList.

// Clearly Unikong is superior so we have to fix that it is not at the top. 
 

 
var list = Array.prototype.slice.call(document.querySelectorAll('ul>li')).reduce(function(init, el) { 
 
    if (el.innerText === 'Unikong') { 
 
    init.splice(0, 0, el); 
 
    } else 
 
    init.push(el); 
 
    return init; 
 
}, []).reduce(function(init, el) { 
 
    init.appendChild(el); 
 
    return init; 
 
}, document.createElement('ul')), 
 
    oldList = document.querySelector('ul'); 
 

 
document.querySelector('ul').parentNode.replaceChild(list, oldList);
<ul> 
 
    <li>One Bunny</li> 
 
    <li>Two Bunny</li> 
 
    <li>Three Bunny</li> 
 
    <li>Unikong</li> 
 
</ul>

2

Попробуйте чтение NodeList в массив:

var cols_array = [].slice.call(cols); 
cols_array.splice(0, 1); 

Вы не можете реально изменить NodeList, он просто представляет собой список узлов, которые нашли querySelectorAll.

+0

я знаю, что это фиксирование путь. Но я не понимаю, почему он не может использовать [] .splice.call прямо ?! [] .slice.call и [] .forEach.call не имеет такой проблемы ... :( – etianQQ

+0

Поскольку ни одна из этих функций не модифицирует массив, а сращивание делает. – Functino