You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何按日期对DIV元素排序?排序函数失效问题求助

解决日期格式排序失效问题

核心问题分析

你当前的问题在于:data-date存储的是经过toLocaleDateString()格式化后的日期(如2023. 01. 28.),这种格式无法通过转数字相减的方式完成正确排序。而从Sanity获取的原始ISO日期(2023-01-28T12:10:00.000Z)本身具备天然可排序性——ISO日期的字符串字典序与时间顺序完全一致。

最优解决方案

无需修改Sanity查询结果,只需分离排序用的原始日期和显示用的格式化日期:

1. 调整React组件的data-date属性

将data-date的值改为Sanity返回的原始publishedAt(ISO格式字符串),显示部分依然保留toLocaleDateString()的格式化逻辑:

<div className="blogboxes" key={index} data-date={post.publishedAt} >
  {/* 其他渲染内容不变 */}
  {/* 如需显示日期,单独处理:*/}
  <div className="publish-time">{new Date(post.publishedAt).toLocaleDateString()}</div>
</div>

2. 修正排序函数逻辑

直接利用ISO日期的可比较特性,两种实现方式可选:

const orderBy = () => {
  const $wrapper = $('#list');
  $wrapper.find('.blogboxes').sort(function (a, b) {
    // 方法1:直接比较ISO字符串(推荐,性能更优)
    return b.dataset.date.localeCompare(a.dataset.date);
    // 方法2:转换为时间戳数值相减,兼容性更强
    // return new Date(b.dataset.date).getTime() - new Date(a.dataset.date).getTime();
  }).appendTo($wrapper);
};

替代方案(必须使用格式化日期时)

如果因业务限制必须用toLocaleDateString()的结果做排序,可以将格式化后的日期转换为标准可排序格式(如YYYYMMDD数字):

// 渲染时生成可排序的日期值
const sortableDate = new Date(post.publishedAt).toISOString().split('T')[0].replace(/-/g, '');
<div className="blogboxes" key={index} data-date={sortableDate} >
  {/* 显示用格式化后的日期 */}
  <div>{new Date(post.publishedAt).toLocaleDateString()}</div>
</div>

排序函数可保持你原有的数值相减逻辑:

return +b.dataset.date - +a.dataset.date;

额外优化建议

避免在scroll事件中频繁触发排序,建议在数据加载完成后仅执行一次排序:

useEffect(()=> {
  sanityClient.fetch('*[_type =="post"]  {title, publishedAt, slug, extract, mainImage{asset-> {_id, url},alt}}')
    .then((data)=> {
      setPost(data);
      // 确保DOM渲染完成后执行排序
      setTimeout(orderBy, 0);
    })
    .catch(console.error);
},[]);

// 移除不必要的scroll事件监听
// window.addEventListener('scroll', orderBy);

内容的提问来源于stack exchange,提问作者Péter Nagy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 10:01:43