在dom中重新排序html元素

时间:2016-01-08 20:14:04

标签: javascript jquery dom

我有一个元素列表:

<div class="wrapper">
    <div class="abc"></div>
    <div class="abc"></div>
    <div class="abc"></div>
</div>

我有一个或多个代表新订单的数字:

var arr = [2,1,0];

我想将这些abc div重新定位到父包装器中的新位置。

重要的是,abc divs附加了事件和数据,这需要保留!

我想出了这个,似乎按预期工作:

var wrapper = $('.wrapper'), items = wrapper.children('div.abc');

var orderedItems = $.map(arr, function(value) {
    return $(items).clone(true,true).get(value);
});
wrapper.empty().html(orderedItems);

我想确保这是正确的方法。

如果可能,我也可以使用javascript解决方案。

5 个答案:

答案 0 :(得分:7)

无需复制所有项目..两次

var wrapper = $('.wrapper'), 
    items = wrapper.children('.abc'),
    arr = [2,1,0];

//items.detach(); if arr doesn't reuse all items
wrapper.append( $.map(arr, function(v){ return items[v] }) );

答案 1 :(得分:5)

如果你想要一个纯粹的Javascript解决方案(不涉及jQuery)

var arr = [2,1,0];
var wrapper = document.getElementsByClassName("wrapper");
var items = wrapper[0].children;
var elements = document.createDocumentFragment();

arr.forEach(function(idx) {
    elements.appendChild(items[idx].cloneNode(true));
});

wrapper[0].innerHTML = null;
wrapper[0].appendChild(elements);

我之前的答案略有改进。小提琴:https://jsfiddle.net/jltorresm/1ukhzbg2/2/

答案 2 :(得分:4)

我知道这是一个老问题,但谷歌引导我。 flexbox(css)上有一个名为'order'的子属性,允许您选择元素的显示顺序。可以使用javascript更改此子属性并重新排序显示的元素。

https://www.w3schools.com/cssref/css3_pr_order.asp

编辑1 - 代码示例:

[1]

答案 3 :(得分:3)

请记住,当添加DOM中已经存在的元素时,该元素将被移动而不是被复制。

CodePen

let wrapper=document.querySelector(".wrapper");
let children=wrapper.children;
let newOrder=[3,2,1,0];
//it means that the first element you want it to be the four element
//The second element you want it to be the third
//the third element you want it to be the second
//the four element you want it to be the first
for(let i=0;i<newOrder.length;i++){
  for(let j=0;j<newOrder.length;j++){
    if(i==newOrder[j]){
      wrapper.appendChild(children[j]);
      break;
    }
  }
}
<div class="wrapper">
  <div>a</div>
  <div>b</div>
  <div>c</div>
  <div>d</div>
</div>

答案 4 :(得分:0)

此解决方案对我来说效果更好,我们构建了一个元素数组([...wrapper.children]),然后根据模型([5,4,3,2,1,0])使用.sort然后我们使用appendChild。由于元素与原始元素相同,因此事件侦听器仍然可以正常工作。这里的代码:

//this is just to add event listeners
[...document.getElementsByClassName("abc")].forEach(e =>
  e.addEventListener("click", ev => console.log(ev.target.innerText))
);

var wrapper = document.getElementsByClassName("wrapper")[0];
var items = [...wrapper.children];

const newOrder = [5,4,3,2,1,0]

items.sort((a, b)=>newOrder.indexOf(items.indexOf(a)) - newOrder.indexOf(items.indexOf(b)));

items.forEach(it=>wrapper.appendChild(it));
<div class="wrapper">
  <div class="abc">0</div>
  <div class="abc">1</div>
  <div class="abc">2</div>
  <div class="abc">3</div>
  <div class="abc">4</div>
  <div class="abc">5</div>
</div>

如您所见,如果单击0、1等,则事件侦听器将起作用。