对列表进行排序在jQuery中无法正常工作

时间:2019-11-27 14:44:59

标签: jquery sorting

我在jQuery上对数据属性创建了4种排序方式。但是,当我单击排序选项时,它总是会按字母顺序从A-Z排序一次。当我再次单击排序时,它什么也没做。

当我执行控制台日志以查看单击哪个项目时,会得到以下结果:

za
az

1-10
za
az

因此,它始终以A-Z排序。但老实说,不知道为什么。

这是我的HTML的示例:

<div class="sort">
    <span class="sort__item" id="js-az">A-Z</span>
    <span class="sort__item" id="js-za">Z-A</span>
    <span class="sort__item" id="js-1-10">1-10</span>
    <span class="sort__item" id="js-10-1">10-1</span>
</div>

<div class="row js-songs-sortable" id="all-song-list">
    <div class="col-md-4 col-sm-12" data-count="5" data-name="Strange Days">
        content
    </div>
    <div class="col-md-4 col-sm-12" data-count="1" data-name="Rock Bottom">
        content
    </div>
    <div class="col-md-4 col-sm-12" data-count="1" data-name="Moutain">
        content
    </div>
    <div class="col-md-4 col-sm-12" data-count="3" data-name="Mad Sun">
        content
    </div>
    <div class="col-md-4 col-sm-12" data-count="10" data-name="Another Ugly Tune">
        content
    </div>
</div>

这是我的jQuery代码:

jQuery('body').on('click', '.sort #js-az', function(){
    jQuery(".js-songs-sortable > div").sort(sort_li).appendTo('.js-songs-sortable');

    function sort_li(a,b){
        return (jQuery(b).data('name')) < (jQuery(a).data('name')) ? 1 : -1;    
    }
});

jQuery('body').on('click', '.sort #js-za', function(){
    jQuery(".js-songs-sortable > div").sort(sort_li).appendTo('.js-songs-sortable');

    function sort_li(b,a){
        return (jQuery(b).data('name')) < (jQuery(a).data('name')) ? 1 : -1;    
    }
});

jQuery('body').on('click', '.sort #js-1-10', function(){
    jQuery(".js-songs-sortable > div").sort(sort_li).appendTo('.js-songs-sortable');

    function sort_li(a,b){
        return (jQuery(b).data('count')) < (jQuery(a).data('count')) ? 1 : -1;    
    }
});

jQuery('body').on('click', '.sort #js-10-1', function(){
    jQuery(".js-songs-sortable > div").sort(sort_li).appendTo('.js-songs-sortable');

    function sort_li(b,a){
        return (jQuery(b).data('count')) < (jQuery(a).data('count')) ? 1 : -1;    
    }
});

您可以在此处找到实时预览: https://mpdb.space/mp-songs/

3 个答案:

答案 0 :(得分:1)

here所述,默认情况下,newAnimal方法按字母顺序和升序将值排序为字符串。但是,您可以通过传递比较函数来修改其行为。您尚未指定要获得的结果,因此必须创建具有所需排序逻辑的函数。

答案 1 :(得分:1)

数据属性总是返回一个字符串(顺便说一句,输入字段也是常见错误),其比较结果不同于数字比较:

console.log( "9" > "111" ) // true
console.log( "310" > "31" ) // true

您必须将它们转换为带有一元+的数字:

( +$(a).data('count') < +$(b).data('count') ) ? -1 : 1;

但是因为您需要返回任何正数或负数,所以可以减去它们。 -运算符将自动将它们转换为数字。

$('#js-az').on('click', function() {
  $(".js-songs-sortable > div").sort(sort_li).appendTo('.js-songs-sortable');
  
  function sort_li(a, b) {
    return ( $(a).data('name') < $(b).data('name') ) ? -1 : 1;
  }
});

$('#js-za').on('click', function() {
  $(".js-songs-sortable > div").sort(sort_li).appendTo('.js-songs-sortable');

  function sort_li(a, b) {
    return ( $(a).data('name') > $(b).data('name') ) ? -1 : 1;
  }
});

$('#js-1-10').on('click', function() {
  $(".js-songs-sortable > div").sort(sort_li).appendTo('.js-songs-sortable');
  
  function sort_li(a, b) {
    return $(a).data('count') - $(b).data('count');
  }
});

$('#js-10-1').on('click', function() {
  $(".js-songs-sortable > div").sort(sort_li).appendTo('.js-songs-sortable');

  function sort_li(a, b) {
    return $(b).data('count') - $(a).data('count')
  }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<div class="sort">
  <span class="sort__item" id="js-az">A-Z</span>
  <span class="sort__item" id="js-za">Z-A</span>
  <span class="sort__item" id="js-1-10">1-10</span>
  <span class="sort__item" id="js-10-1">10-1</span>
</div>

<div class="row js-songs-sortable" id="all-song-list">
  <div data-count="5" data-name="Strange Days">data-count="5" data-name="Strange Days"</div>
  <div data-count="1" data-name="Rock Bottom">data-count="1" data-name="Rock Bottom"</div>
  <div data-count="1" data-name="Moutain">data-count="1" data-name="Moutain"</div>
  <div data-count="3" data-name="Mad Sun">data-count="3" data-name="Mad Sun"</div>
  <div data-count="10" data-name="Another Ugly Tune">data-count="10" data-name="Another Ugly Tune"</div>
</div>

代码的简化版本:

var funcStorage = {
  az: (a, b) => $(a).data('name') < $(b).data('name') ? -1 : 1,
  za: (a, b) => $(a).data('name') > $(b).data('name') ? -1 : 1,
  "1-10": (a, b) => $(a).data('count') - $(b).data('count'),
  "10-1": (a, b) => $(b).data('count') - $(a).data('count'),
}; // If this seems `Alien-code`, Google → JS objects, JS arrow functions

//          (a,b) => a - b               The same
// function (a,b) { return a - b }       thig.

$('.sort__item').each(function(){
  $(this).on('click', function(){
    var func = funcStorage[ this.id.replace("js-","") ];
    // in fact, you don't need id, could store the sort key in data-sort
    $(".js-songs-sortable > div").sort(func).appendTo('.js-songs-sortable');
    
    $('.sort__item.active').removeClass('active');
    $(this).addClass('active');
  });
});
.sort__item {
  display: inline-block;
  cursor: pointer;
  border: 2px solid orange;
  margin: 5px;
  padding: 5px;
}

.sort__item.active { background-color: orange; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<div class="sort">
  <span class="sort__item" id="js-az">A-Z</span>
  <span class="sort__item" id="js-za">Z-A</span>
  <span class="sort__item" id="js-1-10">1-10</span>
  <span class="sort__item" id="js-10-1">10-1</span>
</div>

<div class="row js-songs-sortable" id="all-song-list">
  <div data-count="5" data-name="Strange Days">data-count="5" data-name="Strange Days"</div>
  <div data-count="1" data-name="Rock Bottom">data-count="1" data-name="Rock Bottom"</div>
  <div data-count="1" data-name="Moutain">data-count="1" data-name="Moutain"</div>
  <div data-count="3" data-name="Mad Sun">data-count="3" data-name="Mad Sun"</div>
  <div data-count="10" data-name="Another Ugly Tune">data-count="10" data-name="Another Ugly Tune"</div>
</div>

答案 2 :(得分:0)

代码存在的问题是您正在使用.data,而您需要使用.attr()

jQuery('body').on('click', '.sort #js-az', function() {
  jQuery(".js-songs-sortable > div").sort(sort_li).appendTo('.js-songs-sortable');

  function sort_li(a, b) {
    return (jQuery(b).attr('data-name')) < (jQuery(a).attr('data-name')) ? 1 : -1;
  }
});

jQuery('body').on('click', '.sort #js-za', function() {
  jQuery(".js-songs-sortable > div").sort(sort_li).appendTo('.js-songs-sortable');

  function sort_li(b, a) {
    return (jQuery(b).attr('data-name')) < (jQuery(a).attr('data-name')) ? 1 : -1;
  }
});

jQuery('body').on('click', '.sort #js-1-10', function() {
  jQuery(".js-songs-sortable > div").sort(sort_li).appendTo('.js-songs-sortable');

  function sort_li(a, b) {
    return (parseInt(jQuery(b).attr('data-count'))) < parseInt((jQuery(a).attr('data-count'))) ? 1 : -1;
  }
});

jQuery('body').on('click', '.sort #js-10-1', function() {
  jQuery(".js-songs-sortable > div").sort(sort_li).appendTo('.js-songs-sortable');

  function sort_li(b, a) {
    return parseInt(jQuery(b).attr('data-count')) < parseInt(jQuery(a).attr('data-count')) ? 1 : -1;
  }
});
.sort {
  border-radius: 5px;
  background-color: #eee;
  display: inline-block;
  margin-bottom: 1rem;
}

.sort span {
  padding: 1rem;
  cursor: pointer;
  transition: all 0.3s;
  display: inline-block;
}

.sort span:hover {
  background-color: rgba(0, 0, 0, 0.1);
}

.row>div {
  padding: 0.5rem;
}

.row>div::after {
  content: "data-count= " attr(data-count) " data-name= " attr(data-name);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="sort">
  <span class="sort__item" id="js-az">A-Z</span>
  <span class="sort__item" id="js-za">Z-A</span>
  <span class="sort__item" id="js-1-10">1-10</span>
  <span class="sort__item" id="js-10-1">10-1</span>
</div>

<div class="row js-songs-sortable" id="all-song-list">
  <div class="col-md-4 col-sm-12" data-count="5" data-name="Strange Days">

  </div>
  <div class="col-md-4 col-sm-12" data-count="1" data-name="Rock Bottom">

  </div>
  <div class="col-md-4 col-sm-12" data-count="1" data-name="Moutain">

  </div>
  <div class="col-md-4 col-sm-12" data-count="3" data-name="Mad Sun">

  </div>
  <div class="col-md-4 col-sm-12" data-count="10" data-name="Another Ugly Tune">

  </div>
</div>

此外,您可以为维护性和可读性而对代码进行一些更改。参见以下示例:

jQuery('body').on('click', '.sort__item', function() {
  const id = jQuery(this).attr("id");

  jQuery(".js-songs-sortable > div").sort(function(a, b) {
    let firstEl = jQuery(a);
    let secondEl = jQuery(b);
    let $return = 0;

    switch (id) {
      case "js-az":
        $return = (firstEl.attr('data-name') > secondEl.attr('data-name')) ? 1 : -1;
        break;

      case "js-za":
        $return = (firstEl.attr('data-name') < secondEl.attr('data-name')) ? 1 : -1;
        break;

      case "js-1-10":
        $return = (parseInt(firstEl.attr('data-count')) > parseInt(secondEl.attr('data-count'))) ? 1 : -1;
        break;

      case "js-10-1":
        $return = (parseInt(firstEl.attr('data-count')) < parseInt(secondEl.attr('data-count'))) ? 1 : -1;
        break;
    }

    return $return;
  }).appendTo('.js-songs-sortable');
});
.sort {
  border-radius: 5px;
  background-color: #eee;
  display: inline-block;
  margin-bottom: 1rem;
}

.sort span {
  padding: 1rem;
  cursor: pointer;
  transition: all 0.3s;
  display: inline-block;
}

.sort span:hover {
  background-color: rgba(0, 0, 0, 0.1);
}

.row>div {
  padding: 0.5rem;
}

.row>div::after {
  content: "data-count= " attr(data-count) " data-name= " attr(data-name);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="sort">
  <span class="sort__item" id="js-az">A-Z</span>
  <span class="sort__item" id="js-za">Z-A</span>
  <span class="sort__item" id="js-1-10">1-10</span>
  <span class="sort__item" id="js-10-1">10-1</span>
</div>

<div class="row js-songs-sortable" id="all-song-list">
  <div class="col-md-4 col-sm-12" data-count="5" data-name="Strange Days">

  </div>
  <div class="col-md-4 col-sm-12" data-count="1" data-name="Rock Bottom">

  </div>
  <div class="col-md-4 col-sm-12" data-count="1" data-name="Moutain">

  </div>
  <div class="col-md-4 col-sm-12" data-count="3" data-name="Mad Sun">

  </div>
  <div class="col-md-4 col-sm-12" data-count="10" data-name="Another Ugly Tune">

  </div>
</div>