【问题标题】:Sort child div based on data attribute根据数据属性对子 div 进行排序
【发布时间】:2015-02-02 23:54:35
【问题描述】:

尝试根据数据属性对子 div 进行排序

下面的 html 代码是由 CM 生成的,数据可以按任意随机顺序检索。

html代码是

<section class="box explore">
<div id="ProductContainer"  class="row">
        <div id="1232132" data-name="B" data-category="Category_A" class="explore-cell">
         <h>B</h>
         <p>Category_A</p>
        </div>
    <div id="123" data-name="A" data-category="Category_A" class="explore-cell">
        <h>A</h>
        <p>Category_A</p>
    </div>
    <div id="1232152351" data-name="C" data-category="Category_A" class="explore-cell">
        <h>C</h>
        <p>Category_A</p>
    </div>
    <div id="12342341" data-name="E" data-category="Category_B" class="explore-cell">
        <h>E</h>
        <p>Category_B</p>
    </div>
    <div id="1325321" data-name="D" data-category="Category_B" class="explore-cell">
        <h>D</h>
        <p>Category_B</p>
    </div>

</div>

java

$('div').sort(function (a, b) {

  var contentA = $(a).attr('data-name');
  var contentB = $(b).attr('data-name');
  return (contentA < contentB) ? -1 : (contentA > contentB) ? 1 : 0;

})

Jsfiddle http://jsfiddle.net/w8gkshue/

如果有人能正确地告诉我如何按产品名称或类别进行最佳排序。

更新希望这能提供更好的解释

【问题讨论】:

  • 您是否尝试根据您的排序重新定位 dom 元素?
  • div 会生成行和单元格的网格视图,其中单元格是无序的。我试图使用stackoverflow.com/questions/6133723/… 作为起点,但没有使用字符串

标签: javascript jquery html


【解决方案1】:

编辑:我错过了 jQuery 标记...留下答案。

var productCt = document.getElementById('ProductContainer'),
    reInsertProductCt = tempRemove(productCt);


[].slice.call(productCt.children)
  .sort(function (a, b) {
    var aName = a.dataset.name,
        bName = b.dataset.name;
  
    return aName < bName? -1 : +(aName > bName);
  })
  .forEach(productCt.appendChild.bind(productCt));

reInsertProductCt();





function tempRemove(el) {
    var parent = el.parentNode,
        nextSibling = el.nextSibling;
  
    parent.removeChild(el);
  
    return function () {
        if (nextSibling) parent.insertBefore(el, nextSibling);
        else parent.appendChild(el);
    };
}
<div id="ProductContainer"  class="row">
        <div id="1232132" data-name="B" data-category="Category_A" class="explore-cell">
         <h>TEST NAME B</h>
         <p>TEST</p>
        </div>
    <div id="123" data-name="A" data-category="Category_A" class="explore-cell">
        <h>TEST NAME A</h>
        <p>TEST</p>
    </div>
    <div id="1232152351" data-name="C" data-category="Category_A" class="explore-cell">
        <h>TEST NAME C</h>
        <p>TEST</p>
    </div>
    <div id="12342341" data-name="E" data-category="Category_B" class="explore-cell">
        <h>TEST NAME E</h>
        <p>TEST</p>
    </div>
    <div id="1325321" data-name="D" data-category="Category_B" class="explore-cell">
        <h>TEST NAME D</h>
        <p>TEST</p>
    </div>

</div>

【讨论】:

    【解决方案2】:

    你可以像这样使用 .sort 方法

    var $wrapper = $('#ProductContainer');
    
    $wrapper.find('.explore-cell').sort(function (a, b) {
        return a.getAttribute('data-name') > b.getAttribute('data-name');
    })
    .appendTo( $wrapper );
    

    但我不确定是否支持交叉浏览

    【讨论】:

    • 将是 attech 到 div id 而不是类有多个行类的最佳方法
    • 确实如此,感谢您的建议
    • 很奇怪我会玩我不能让它在本地工作但这是一个好的开始谢谢兄弟
    【解决方案3】:

    仅对它们调用排序实际上不会在视觉上改变 DOM,它只是返回一个排序集合。所以基本上你只需要获取集合,对其进行排序,然后返回它。像这样的东西应该可以工作:

    $('#ProductContainer > div').detach().sort(function (a, b) {
      var contentA = $(a).data('name');
      var contentB = $(b).data('name');
      return (contentA < contentB) ? -1 : (contentA > contentB) ? 1 : 0;
    }).appendTo('#ProductContainer');
    

    您需要确保使用的是 detach() 方法而不是 remove(),因为 detach() 将保留与集合项关联的所有数据和事件。

    【讨论】:

      【解决方案4】:

      既然可以同时按类别或名称排序,为什么还要选择按类别或名称排序?

      我尝试编写一个通用的多排序函数生成器,它应该也可以与原生数组排序函数一起使用。

      JSFIDDLE HERE

      一个生成多重排序的函数,它有两个参数。

      1. 列优先级列表顺序(首先按类别还是按名称?由您决定)。
      2. 我还想要一种为列提供值的方法(因为您可能不会以相同的方式为每个列检索它们),它是一个对象,它为每列描述一个检索数据的函数。

      在这里

      function getMultisortFn(columns, provideColumnData) {
          return function (a, b) {
              for (var i = 0, l = columns.length; i < l; i++) {
                  var column = columns[i];
                  var aColumnData = provideColumnData[column.name](a, column.name);
                  var bColumnData = provideColumnData[column.name](b, column.name);
                  if (aColumnData !== bColumnData) {
                      if (column.asc) {
                          return String.prototype.localeCompare.call(aColumnData, bColumnData);
                      }
      
                      return String.prototype.localeCompare.call(bColumnData, aColumnData);    
                  }
              }
          };
      }
      

      现在这是您实际使用生成的多排序的部分

      function retrieveDataAttribute(item, attribute) {
          return $(item).data(attribute);
      }
      
      var $container = $('#ProductContainer'); 
      var $products = $container.find('div');
      
      var multisort = getMultisortFn([{
              name: 'category',
              asc: false
          }, {
              name: 'name',
              asc: true
          }], {
              name: retrieveDataAttribute,
              category: retrieveDataAttribute
          });
      
      
      
      $products.sort(multisort);
      

      最后是 DOM 操作以应用新订单

      $products.detach().appendTo($container);
      

      编辑 感谢 plalx:

        $container.detach().append($products).appendTo('section.box.explore');
      

      【讨论】:

      • 感谢您的示例
      • 在添加 $products 之前无需分离它们。此外,在附加产品之前要分离 $container 以避免多次回流。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-02-06
      • 1970-01-01
      • 1970-01-01
      • 2011-09-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多