Reputation: 2819
By doing a JavaScript function to move order of HTML elements in a container id="ArticleContents", I had to face the following behavior by trying to move the order of elements in NodeArray with .insertBefore():
$(document).click(function(event) {
currentItemID= event.target.id
//... code to have articleContentSeleted=document.getElementById("DIV I want to move up or down")
if (articleContentSeleted){
childrenExistingRow=document.getElementById("ArticleContents").children;
existingRow=document.getElementById("ArticleContents");
var index = Array.prototype.indexOf.call(ChildrenExistingRow, ArticleContentSeleted);
if (currentItemID =="MoveUp" && index!=0){existingRow.insertBefore(articleContentSeleted,childrenExistingRow[index-1]);};
if (currentItemID =="MoveDown" && index !=childrenExistingRow.length){existingRow.insertBefore(articleContentSeleted,childrenExistingRow[index+2]);};
}
});
It works "almost" from the first try to make the articleContentSeleted moveUP with:
if (currentItemID =="MoveUp" && index!=0){existingRow.insertBefore(articleContentSeleted,childrenExistingRow[index-1]);};
But It requested me many time to manage to do the moveDOWN with:
if (currentItemID =="MoveDown" && index !=childrenExistingRow.length){existingRow.insertBefore(articleContentSeleted,childrenExistingRow[index+2]);};
And now I'm curious to know why
if (currentItemID =="MoveDown" && index !=childrenExistingRow.length){existingRow.insertBefore(articleContentSeleted,childrenExistingRow[index+1]);};
didn't do the job...
console.log(childExistingRow):
HTMLCollection(2) [textarea#Editor_Text1_0, textarea#Editor_img_1, Editor_Text1_0: textarea#Editor_Text1_0, Editor_img_1: textarea#Editor_img_1]
0: textarea#Editor_Text1_0
1: textarea#Editor_img_1
length: 2
Editor_Text1_0: textarea#Editor_Text1_0
Editor_img_1: textarea#Editor_img_1
__proto__: HTMLCollection
The behavior is the same if childExistingRow contains 2, 3 or 10 elements...
Upvotes: 0
Views: 27
Reputation: 13225
insertBefore()
itself seems to work well, using the xysibling properties you can avoid dealing with indices, lookups and the like:
let cnt=0;
function up(event) {
let node = event.target.parentNode;
let container = node.parentNode;
if (node.previousElementSibling)
container.insertBefore(node, node.previousElementSibling);
log.innerText=++cnt;
}
function down(event) {
let node = event.target.parentNode;
let container = node.parentNode;
if (node.nextElementSibling)
container.insertBefore(node, node.nextElementSibling.nextElementSibling);
log.innerText=++cnt;
}
<div>
<div style="background:red">
<button onclick="up(event)"><</button>
1
<button onclick="down(event)">></button>
</div>
<div style="background:green">
<button onclick="up(event)"><</button>
2
<button onclick="down(event)">></button>
</div>
<div style="background:lightblue">
<button onclick="up(event)"><</button>
3
<button onclick="down(event)">></button>
</div>
</div>
Clicks:<span id="log">0</span>
Maybe I understand your question after all:
existingRow.insertBefore(articleContentSeleted,childrenExistingRow[index+1]);
Inserts the row before the row it follows it, back to its current place. Remember that it's not about indices, but the items.
So it's not 1) remove X from index x, 2) all indices shift one down, 3) insert X before the element which is at index x+1 now.
But more like 1) take item Y at position x+1, 2) remove X from index x, 3) insert X before item Y. Back to its original place.
That's why the example has container.insertBefore(node, node.nextElementSibling.nextElementSibling);
, also using that
referenceNode
The node before whichnewNode
is inserted. If this isnull
, thennewNode
is inserted at the end ofparentNode
's child nodes.
(from docs)
Upvotes: 1