【问题标题】:jQuery, how to get elements with data-attribute value that contains "/" and sort themjQuery,如何获取具有包含“/”的数据属性值的元素并对它们进行排序
【发布时间】:2019-03-29 17:13:02
【问题描述】:

我正在尝试根据数据属性获取包含特定字符串或值的元素,并对它们进行排序,因为它们是日期。我找到了一个很好的 JSFiddle 示例,它获取数据属性值,然后将其转换为 Epoch 日期格式(目前还可以),然后对它们进行排序。但它只在第一次加载自调用功能页面时对它们进行排序。当我将它包装在一个函数中并尝试再次调用它时,顺序从 ASC 切换到 DESC,而不仅仅是保持 ASC 或 DESC 顺序。
也就是说,我有一个基于我找到的示例的 JSFiddle,但是现在当我尝试不断对日期进行排序并保持 ASC 或 DESC 格式时,转换为 Epoch 时间的数据值正在获取 NaN。

所以我尝试将其包装在 IF 语句中,以查看数据属性值是否包含“/”,但现在似乎也不起作用。我的 Fiddle 中有一堆我一直在研究的 cmets。我非常接近,但是当我每次尝试单击排序功能时,我希望订单保持不变而不会出错(检查控制台你会看到 NaN)。

这是使用原始代码的 Fiddle 示例,但我将它包装在一个函数中并通过单击调用它,并且每次的顺序都会反转。我只希望它去 ASC 或 DESC,而不是来回切换。 http://jsfiddle.net/r8hbx2e3/1/

//ORIGINALLY BASED ON http://jsfiddle.net/greguarr/2fr0vmhu/
//BUT THIS JUST REORDERS EVERYTHING ASC AND DESC ON EVERY CLICK.  JUST WANT IT ONE OR THE OTHER 
//HOW DO YOU GET THIS TO STOP REVERSING ORDER.

//ONE I HAVE BEEN WORKING ON IS HERE: http://jsfiddle.net/ndh9Lyuj/5/

function sortItems() {
  var container = $(".sort-list");
  var items = $(".sort-item");

  items.each(function() {
    // Convert the string in 'data-event-date' attribute to a more
    // standardized date format
    var BCDate = $(this).attr("data-event-date").split("/");
    var standardDate = BCDate[0] + " " + BCDate[1] + " " + BCDate[2];
    standardDate = new Date(standardDate).getTime();
    $(this).attr("data-event-date", standardDate);
  });

  items.sort(function(a, b) {
    a = parseFloat($(a).attr("data-event-date"));
    b = parseFloat($(b).attr("data-event-date"));
    return a > b ? -1 : a < b ? 1 : 0;
  }).each(function() {
    container.prepend(this);
  });
};

$('p').on('click', function() {
  sortItems();
});

/* This script sorts your list in descending order... to change it to ascending order change the "less than" operator (<) to "greater than" (>) */
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.0.0/jquery.min.js"></script>
<ul class="sort-list">
  <li class="sort-item" data-event-date="01/20/2019">01/20/2019</li>
  <li class="sort-item" data-event-date="10/15/2017">10/15/2017</li>
  <li class="sort-item" data-event-date="11/14/2018">11/14/2018</li>
  <li class="sort-item" data-event-date="02/05/2016">02/05/2016</li>
  <li class="sort-item" data-event-date="10/31/2013">10/31/2013</li>
</ul>
<p>
  Click me
</p>

这是我一直在努力尝试使多个选项起作用但保持顺序不切换的更广泛的 Fiddle。但它并不完全有效,因为您会在控制台中看到 NaN 在第一次点击后每次都会返回。 http://jsfiddle.net/ndh9Lyuj/5/

//ORIGINALLY BASED ON http://jsfiddle.net/greguarr/2fr0vmhu/

var container = $(".sort-list");
var items = $(".sort-item");
var yourArray = [];

function me() {
  items.each(function() {
    console.log("up top" + $(this).attr("data-event-date"));
    // Convert the string in 'data-event-date' attribute to a more
    // standardized date format

    if ($(this).attr("data-event-date").indexOf("/")) { //This does not seem to be working to check if data attribute has value with a slash. 
      var BCDate = $(this).attr("data-event-date").split("/");
      var standardDate = BCDate[0] + " " + BCDate[1] + " " + BCDate[2];
      standardDate = new Date(standardDate).getTime();
      $(this).attr("data-event-date", standardDate);
      console.log("with standard date " + $(this).attr("data-event-date"));
    }
    console.log($(this).attr("data-event-date"));
    // yourArray.push($(this).prop('data-event-date').split(' ')[0]);
  });

  //    nowSort(items);
  //    }
  //function nowSort(items){
  items.sort(function(a, b) {
      a = parseFloat($(a).attr("data-event-date"));
      b = parseFloat($(b).attr("data-event-date"));
      // if(a < b){
      // return -1
      //}
      // return 0;
      // a = $(a).attr("data-event-date");
      // b = $(b).attr("data-event-date");
      return a > b ? -1 : a < b ? 1 : 0;
      // return a > b;
      //alert('sort');
    })
    .each(function() {
      container.prepend(this);
    });
  //alert('sort');
}

$('p').on('click', function() {
  me();
});

/* This script sorts your list in descending order... to change it to ascending order change the "less than" operator (<) to "greater than" (>) */
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.0.0/jquery.min.js"></script>
<ul class="sort-list">
  <li class="sort-item" data-event-date="04/20/2019">04/20/2019</li>
  <li class="sort-item" data-event-date="03/05/2017">03/05/2017</li>
  <li class="sort-item" data-event-date="04/18/2019">04/18/2019</li>
  <li class="sort-item" data-event-date="01/20/2016">01/20/2016</li>
  <li class="sort-item" data-event-date="10/31/2019">10/31/2019</li>
  <li class="sort-item" data-event-date="02/30/2019">02/31/2019</li>
</ul>
<p>
  click me
</p>

感谢任何帮助。

【问题讨论】:

  • 添加了嵌入式代码 sn-ps。我很抱歉第一次没有把整个事情都包括在内。
  • 评估脚本时的小注解; return a &gt; b ? -1 : a &lt; b ? 1 : 0; 可以只是 return b - a;
  • @Taplar 谢谢,很高兴知道。

标签: javascript jquery sorting


【解决方案1】:
  • 更改了传入ascdesc的方法
  • 仅转换一次日期,并将其转换为 ISO 格式
  • 不要覆盖原始数据字段
  • 排序时,检查值是否为asc,以确定排序方式

$('p').on('click', function(){ sortItems('desc'); });

function sortItems (sortDirection) {
  var container = $(".sort-list");
  var items = $(".sort-item");

  items.filter(function(){
    return !$(this).data('convertedEventDate');
  }).each(function() {
    var BCDate = $(this).data("eventDate").split("/");
    var standardDate = `${BCDate[2]}-${BCDate[0]}-${BCDate[1]}`;
    
    standardDate = new Date(standardDate).getTime();
    $(this).data("convertedEventDate", standardDate);
  });
  
  container.append(
    items.sort(function(a, b){
      var $aTime = $(a).data('convertedEventDate');
      var $bTime = $(b).data('convertedEventDate');
      
      if (sortDirection === 'asc') {
        return $aTime - $bTime;
      } else {
        return $bTime - $aTime;
      }
    })
  );
};
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.0.0/jquery.min.js"></script>
<ul class="sort-list">
  <li class="sort-item" data-event-date="01/20/2019">01/20/2019</li>
  <li class="sort-item" data-event-date="10/15/2017">10/15/2017</li>
  <li class="sort-item" data-event-date="11/14/2018">11/14/2018</li>
  <li class="sort-item" data-event-date="02/05/2016">02/05/2016</li>
  <li class="sort-item" data-event-date="10/31/2013">10/31/2013</li>
</ul>

<p>Click me</p>

【讨论】:

  • 完美运行!一个问题,这只是为了自己的理解,在 HTML 中 data 属性是 'data-event-date' 但在 JS 中是 var BCDate = $(this).data("eventDate").split("/ ");但它仍然有效,你能解释一下为什么吗?
  • 您提供给data() 的驼峰式密钥将根据驼峰式的位置转换为包含破折号。而data() 特别适用于 data-* 属性,因此它会处理前缀并且您将其关闭。 @ClosDesign
  • 有趣。我不知道。谢谢!
猜你喜欢
  • 2021-03-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-06-09
  • 1970-01-01
  • 2015-02-17
相关资源
最近更新 更多