如何按日期对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
相关产品推荐
相关产品推荐

