【问题标题】:Reverse order of a set of HTML elements一组 HTML 元素的反转顺序
【发布时间】:2011-12-18 01:39:06
【问题描述】:

我有一组看起来像这样的 div:

<div id="con">
    <div> 1 </div>
    <div> 2 </div>
    <div> 3 </div>
    <div> 4 </div>
    <div> 5 </div>
</div>

但我希望它们翻转,使其看起来像这样:

<div> 5 </div>
<div> 4 </div>
<div> 3 </div>
<div> 2 </div>
<div> 1 </div>

这样当添加新的&lt;div&gt; 时,它会进入列表的末尾。

我该怎么做(或者有更好的方法)?

【问题讨论】:

  • “这样当添加一个 div 时,它将转到列表的末尾......” - 你的问题是如何反转现有元素(一些很好的答案对于下面的),或者如何在特定位置添加新元素?从您想要的输出开始,如果您添加了一个新的&lt;div&gt;6&lt;/div&gt;,它应该低于 1 还是高于 5?

标签: javascript html jquery sorting appendchild


【解决方案1】:

一个普通的 JS 解决方案:

function reverseChildren(parent) {
    for (var i = 1; i < parent.childNodes.length; i++){
        parent.insertBefore(parent.childNodes[i], parent.firstChild);
    }
}

【讨论】:

【解决方案2】:

总结为一个不错的 jQuery 函数,可用于任何一组选择:

$.fn.reverseChildren = function() {
  return this.each(function(){
    var $this = $(this);
    $this.children().each(function(){ $this.prepend(this) });
  });
};
$('#con').reverseChildren();

证明:http://jsfiddle.net/R4t4X/1/

编辑:已修复以支持任意 jQuery 选择

【讨论】:

  • +1 易于任何开发人员阅读、理解、维护和更改。
  • 你救了我的命!!谢谢
【解决方案3】:

我发现以上所有内容都不令人满意。这是一个香草 JS 单线:

parent.append(...Array.from(parent.childNodes).reverse());  

带有解释的片段:

// Get the parent element.
const parent = document.getElementById('con');
// Shallow copy to array: get a `reverse` method.
const arr = Array.from(parent.childNodes);
// `reverse` works in place but conveniently returns the array for chaining.
arr.reverse();
// The experimental (as of 2018) `append` appends all its arguments in the order they are given. An already existing parent-child relationship (as in this case) is "overwritten", i.e. the node to append is cut from and re-inserted into the DOM.
parent.append(...arr);
<div id="con">
  <div> 1 </div>
  <div> 2 </div>
  <div> 3 </div>
  <div> 4 </div>
  <div> 5 </div>
</div>

【讨论】:

    【解决方案4】:

    没有库:

    function reverseChildNodes(node) {
        var parentNode = node.parentNode, nextSibling = node.nextSibling,
            frag = node.ownerDocument.createDocumentFragment();
        parentNode.removeChild(node);
        while(node.lastChild)
            frag.appendChild(node.lastChild);
        node.appendChild(frag);
        parentNode.insertBefore(node, nextSibling);
        return node;
    }
    
    reverseChildNodes(document.getElementById('con'));
    

    jQuery 风格:

    $.fn.reverseChildNodes = (function() {
        function reverseChildNodes(node) {
            var parentNode = node.parentNode, nextSibling = node.nextSibling,
                frag = node.ownerDocument.createDocumentFragment();
            parentNode.removeChild(node);
            while(node.lastChild)
                frag.appendChild(node.lastChild);
            node.appendChild(frag);
            parentNode.insertBefore(node, nextSibling);
            return node;
        };
        return function() {
            this.each(function() {
                reverseChildNodes(this);
            });
            return this;
        };
    })();
    
    $('#con').reverseChildNodes();
    

    jsPerf Test

    【讨论】:

    • 是的,与下面的解决方案相比,所有人都很难阅读,因此很难更改和维护。
    • @Phrogz 和 Michael Durrant:如果你更喜欢两次回流而不是this version
    • @Saxoier 是一个比接受的答案更好的解决方案,因为它不依赖于 jQuery,或者更重要的是在处理大量元素时会导致重排。
    【解决方案5】:

    一种方式:

    function flip(){
     var l=$('#con > div').length,i=1;
     while(i<l){
       $('#con > div').filter(':eq(' + i + ')').prependTo($('#con'));
       i++;
     }
    }
    

    【讨论】:

    • 这对我有用,因为我的父 div 有其他动态添加的子元素,我需要精确匹配。
    【解决方案6】:

    另一个(更简单?)vanilla javascript 响应:http://jsfiddle.net/d9fNv/

    var con = document.getElementById('con');
    var els = Array.prototype.slice.call(con.childNodes);
    for (var i = els.length -1; i>=0; i--) {
        con.appendChild(els[i]);
    }
    

    或者,一种更短但效率较低的方法:http://jsfiddle.net/d9fNv/1/

    var con = document.getElementById('con');
    Array.prototype.slice.call(con.childNodes).reverse().forEach(function(el) {
        con.appendChild(el);
    });
    

    【讨论】:

      【解决方案7】:

      早在 2011 年,当有人问这个问题时,Flexbox 才存在 1-2 年,支持并不好,但现在是 2020 年,情况有了很大改善,所以你可以只使用 CSS 来做到这一点!

      您可以尝试使用 Flexbox 的 flex-direction: column-reverse:

      ul {
        display: flex;
        flex-direction: column-reverse;
      }
      <ul>
        <li>1</li>
        <li>2</li>
        <li>3</li>
        <li>4</li>
        <li>5</li>
      </ul>

      如果您想在一个更完整的示例中看到这一点,该示例在 columncolumn-reverse 之间动态切换,请查看另一个问题:How can I reverse the order of div elements upside down on 'onclick'?

      【讨论】:

      • 我认为这个答案可以通过简化为仅弹性框选择器来得到更好的服务。您的普通 Google 搜索者会对此感到不知所措。
      • 是的,你可能是对的。我简化了这个答案,并为另一个更复杂的例子添加了一个链接。谢谢你的提示! ??
      • Flexbox reverse 只是一种外观技巧,而内部结构并未反转,因此,任何脚本或逻辑迭代 div 元素,它会发现它们仍处于原始顺序,实际上并未反转.这个答案违背了问题的目的,即请求反转“div”元素而不仅仅是在浏览器中呈现 UI。
      • @Abdulhameed 从 OP 的问题中不清楚目标是什么,它还提到“或者有没有更好的方法来做到这一点”。如果目标是美观,那么这将是“更好的方法”。这个答案只是为其他可能不希望/不需要 JS 解决方案来反转实际 DOM 节点的用户提供替代方案。
      猜你喜欢
      • 1970-01-01
      • 2010-12-13
      • 1970-01-01
      • 2020-06-30
      • 1970-01-01
      • 2013-06-15
      • 2021-12-01
      • 2013-10-27
      • 1970-01-01
      相关资源
      最近更新 更多