【问题标题】:Changing the order of elements改变元素的顺序
【发布时间】:2011-12-06 05:42:43
【问题描述】:

我正在创建一个浮动宽度的网站。用户在智能手机上使用从全高清分辨率到大约 600 像素的屏幕,这似乎是一个不错的主意。这带来了一个非常有趣的问题。

当用户使用比最佳分辨率更小的分辨率时,页面会获得更高的高度。这意味着更改某些元素(例如某些图像、搜索框或导航)的顺序可能会很有用,以使页面更具可读性而无需过多浏览。

所以我需要能够访问 DOM 并更改某些页面元素的顺序(交换它们)。

假设我有一个列表,需要交换第 1 项和第 2 项。

<ul>
  <li>1</li>
  <li>2</li>
</ul>

我找到了一个解决方案,该解决方案基于使用函数appendChild 将已项目元素附加到&lt;ul&gt;。然而,文本节点存在问题,对于更困难的元素结构,它变得非常复杂,因为需要再次重新创建它。

您有什么改进建议吗?

【问题讨论】:

  • 花时间学习 jQuery。它使此类活动变得更加容易。
  • 你能说得更具体些吗?我现在是那个库,但一些有用的 API 链接会有所帮助。
  • 你试过使用 jquery sortable 吗? jqueryui.com/sortable

标签: javascript html dom


【解决方案1】:

对于这种简单的情况(交换仅有的两个元素),您可以使用appendChild()

(() => {
  const list = document.querySelector("ul");
  list.appendChild(list.firstElementChild);
})();
<ul>
  <li>List-item #1</li>
  <li>List-item #2</li>
</ul>

同一个节点不能存在多个位置;因此,它会从当前位置移除并放置在集合的末尾。

如果你想做更复杂的排序,你可能应该从 childNodes 中创建一个数组,然后发疯:

(() => {
  const frag = document.createDocumentFragment();
  const list = document.querySelector("ul");
  const items = list.querySelectorAll("li");
  const sortedList = Array.from(items).sort(function(a, b) {
    const c = a.textContent,
      d = b.textContent;
    return c < d ? -1 : c > d ? 1 : 0;
  });
  for (let item of sortedList) {
    frag.appendChild(item);
  }
  list.appendChild(frag);
})();
<ul>
  <li>Dogs</li>
  <li>Snakes</li>
  <li>Cats</li>
  <li>Bugs</li>
</ul>

【讨论】:

    【解决方案2】:

    您可以使用 flex 轻松更改 HTML 元素的顺序。

    flex order: 0 通过更改 order 值,您可以决定元素出现在列中的哪个位置

    const ascButton= document.getElementById('asc')
    const decButton= document.getElementById('dec')
    
    //callback function for soring in ascending order
    const ascending = (a,b)=> a.innerHTML - b.innerHTML
    
    //callback function for soring in descending order
    const descending = (a,b)=> b.innerHTML - a.innerHTML
    
    let currentOrder = ascending
    
    ascButton.addEventListener('click', ()=>{
    	currentOrder = ascending
      order()
    })
    
    
    decButton.addEventListener('click', ()=>{
    	currentOrder = descending
      order()
    })
    
    
    const order  = function(){
    	const ordered = [...document.getElementsByClassName('col')].sort(currentOrder)
      ordered.forEach((elem, index)=>{
      	elem.style.order = index
      })
    }
    
    
    order()
    .row{
      display: flex;
      flex-direction: column;
    }
    .col{
      padding: 20px;
      border: 1px solid gray;
      margin: 5px;
      order:3;
    }
    <div class="row">
      <div class="col "   id="one">1</div>
      <div class="col "   id="two">2</div>
      <div class="col " id="three">3</div>
      <div class="col " id="ten">10</div>
      <div class="col "  id="four">4</div>
      <div class="col "  id="five">5</div>
    </div>
    
    <button id="asc">ASC</button>
    <button id="dec">DESC</button>

    你可以在这里找到更复杂的实现https://jsfiddle.net/nijeesh4all/on5rsax8/

    【讨论】:

    • 我喜欢在您更复杂的示例中使用data-* 属性。它使过滤的内容更清楚?
    • 我喜欢使用弹性订单的想法,谢谢!
    【解决方案3】:

    在 2018 年(并且已经是几年前),仅使用 CSS 就可以做到这一点。您的用例将通过以下方式解决:

    ul {
      display: flex;
      flex-direction: column;
    }
    
    li:nth-child(2) {
      order: -1;
    }
    

    【讨论】:

    • 太糟糕了flex 不起作用/在字段集上有错误:(
    【解决方案4】:

    难道不交换 innerHTML 也可以吗?

    var myList = document.getElementsByTagName("ul")[0]; 
    temp = myList.getElementsByTagName("li")[0].innerHTML;
    myList.getElementsByTagName("li")[0].innerHTML = myList.getElementsByTagName("li")[1].innerHTML;
    myList.getElementsByTagName("li")[1].innerHTML = temp;
    

    【讨论】:

    • 在写入 innerHTML 时要小心,它可能会对事件处理程序和其他此类属性产生不良影响。例如:stackoverflow.com/a/5113120/370786
    • 当您尝试使用 document.body 时会发生这种情况,但在这种情况下不会。一个简单的例子 -> jsfiddle.net/tzv5db93
    猜你喜欢
    • 1970-01-01
    • 2023-04-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-12
    • 2019-08-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多