使用纯 JS 对 DOM 元素进行排序

zor*_*vic 4 javascript sorting

<div class="items">

<div class="item" id="item1">
    <h4>name</h4>
    <img src="">
    <p class="price"></p>
</div>

<div class="item" id="item2">
    <h4>name</h4>
    <img src="">
    <p class="price"></p>
</div>

<div class="item" id="item4">
    <h4>name</h4>
    <img src="">
    <p class="price"></p>
</div>
Run Code Online (Sandbox Code Playgroud)

在这种布局中,仅使用 JS 按“价格”对项目进行排序的最简单方法是什么?比如说,有一个有商品的网店,用户想要按价格升序对商品进行排序

Pra*_*lan 5

使用Array#sort具有自定义排序功能的方法。

// get the aprent element
var parent = document.querySelector('.items');

// get all children element and convert into array
// for newer browser you can use `Array.from` instead
// of `[].slice.call()`
[].slice.call(parent.children)
  // sort them using custom sort function
  .sort(function(a, b) {
    // get text content in .price and return difference
    return getPrice(a) - getPrice(b);
    // iterate and append again in new sorted order
  }).forEach(function(ele) {
    parent.appendChild(ele);
  })

// function for getting the price value from the element
function getPrice(ele) {
  // parse the string
  return Number(ele
      // get the price element
      .querySelector('.price')
      // get text content
      .textContent
      // replace all char except digit and dot
      .replace(/[^\d.]+/g, ''))
      // or instead of replace use match method to 
      // get price value
      // .match(/\d*(?:\.\d+)?/)[0]
    // return 0 if NaN
    || 0;
}
Run Code Online (Sandbox Code Playgroud)
<div class="items">

  <div class="item" id="item1">
    <h4>name</h4>
    <img src="">
    <p class="price">1</p>
  </div>

  <div class="item" id="item2">
    <h4>name</h4>
    <img src="">
    <p class="price">23</p>
  </div>

  <div class="item" id="item4">
    <h4>name</h4>
    <img src="">
    <p class="price">3</p>
  </div>
</div>
Run Code Online (Sandbox Code Playgroud)


更新:要根据下拉列表更改顺序,请使用侦听器执行此类操作。

var parent = document.querySelector('.items'),
  sel = document.querySelector('#order');

function sortElement() {
  [].slice.call(parent.children)
    .sort(function(a, b) {
      // change return value based on order
      return sel.value * (getPrice(a) - getPrice(b));
    }).forEach(function(ele) {
      parent.appendChild(ele);
    })
}

function getPrice(ele) {
  return Number(ele
      .querySelector('.price')
      .textContent
      .replace(/[^\d.]+/g, ''))
    // .match(/\d*(?:\.\d+)?/)[0]
    || 0;
}

// initially sort the element
sortElement();
// bind click event handler
sel.addEventListener('change', sortElement);
Run Code Online (Sandbox Code Playgroud)
<select id="order">
  <option value="1" selected>a-b</option>
  <option value="-1">b-a</option>
</select>
<div class="items">

  <div class="item" id="item1">
    <h4>name</h4>
    <img src="">
    <p class="price">1</p>
  </div>

  <div class="item" id="item2">
    <h4>name</h4>
    <img src="">
    <p class="price">23</p>
  </div>

  <div class="item" id="item4">
    <h4>name</h4>
    <img src="">
    <p class="price">3</p>
  </div>
</div>
Run Code Online (Sandbox Code Playgroud)

  • @Rajesh 需要引用 - 为什么被认为不好,由谁引用?像这样的循环追加非常有效,因为`parent.append(child)` 会将 _same_ 元素(可能有事件处理程序等)移动到正确的位置。 (2认同)