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

如何简化JavaScript时间差代码并解决Jekyll多帖子批量渲染问题

搞定Jekyll多帖子自动渲染时间差的小技巧

我之前也碰到过类似的麻烦——写了个计算时间差的JS函数,结果每个帖子都要手动写JS代码才能渲染,还要在Front-matter里加一堆自定义ID,简直太折腾了。后来摸索出一套简化方案,不用再手动折腾ID,还能自动给所有帖子渲染“X小时前”这种格式,给你分享一下:

第一步:砍掉Front-matter里的冗余配置

之前你在每个帖子里写postedago和postedon完全没必要,Jekyll自带的变量就能帮我们生成唯一标识。直接把Front-matter简化成这样就行:

---
date: 2018-1-4 02:00:00 +0100
---

省得每次发新帖都要手动加那两个ID字段,省心不少。

第二步:统一帖子时间的HTML结构

把帖子模板里的<time>标签改成用class和自定义数据属性的结构,让JS能批量识别和处理:

<time class="post-time" datetime="{{ post.date | date_to_xmlschema }}" data-post-date="{{ post.date | date_to_rfc822 }}">
  <span class="time-ago"></span>
</time>

这里用class="post-time"代替原来的ID,方便JS批量获取所有时间元素;data-post-date用来存储帖子的原始发布日期,这样JS不用依赖ID就能拿到日期数据。

第三步:重构JS实现自动批量渲染

你的ago()函数逻辑没问题,我们只需要加个初始化函数,让页面加载完成后自动遍历所有帖子的时间元素,批量渲染时间差:

// 保留你原来的时间差计算函数
function ago(date) {
  function render(n, unit) {
    return n + " " + unit + ((n == 1) ? "" : "s") + " ago";
  }
  var seconds = Math.floor((new Date() - date) / 1000);
  var interval = Math.floor(seconds / (60 * 60 * 24 * 30 * 365));
  if (interval >= 1) {
    return render(interval, "year");
  }
  interval = Math.floor(seconds / (60 * 60 * 24 * 30));
  if (interval >= 1) {
    return render(interval, "month");
  }
  interval = Math.floor(seconds / (60 * 60 * 24));
  if (interval >= 1) {
    return render(interval, "day");
  }
  interval = Math.floor(seconds / (60 * 60));
  if (interval >= 1) {
    return render(interval, "hour");
  }
  interval = Math.floor(seconds / 60);
  if (interval >= 1) {
    return render(interval, "minute");
  }
  interval = Math.floor(seconds);
  return render(interval, "second");
}

// 新增自动初始化函数,批量处理所有帖子的时间
function initTimeAgo() {
  // 获取所有帖子的时间元素
  const timeElements = document.querySelectorAll('.post-time');
  timeElements.forEach(el => {
    // 从data属性里读取发布日期,转换成Date对象
    const postDate = new Date(el.dataset.postDate);
    // 找到要渲染时间差的span元素
    const timeAgoSpan = el.querySelector('.time-ago');
    if (timeAgoSpan) {
      timeAgoSpan.textContent = ago(postDate);
    }
  });
}

// 页面加载完成后自动执行初始化
document.addEventListener('DOMContentLoaded', initTimeAgo);

这样一来,不管你有多少帖子,页面加载后都会自动渲染时间差,再也不用给每个帖子写单独的JS代码了。

可选优化:让时间差实时更新

如果想要时间差能自动刷新(比如过了一小时自动从“1小时前”变成“2小时前”),可以加个定时器,每隔一分钟更新一次:

// 新增更新函数
function updateTimeAgo() {
  const timeElements = document.querySelectorAll('.post-time');
  timeElements.forEach(el => {
    const postDate = new Date(el.dataset.postDate);
    const timeAgoSpan = el.querySelector('.time-ago');
    if (timeAgoSpan) {
      timeAgoSpan.textContent = ago(postDate);
    }
  });
}

// 页面加载时初始化,之后每隔60秒更新一次
document.addEventListener('DOMContentLoaded', () => {
  initTimeAgo();
  setInterval(updateTimeAgo, 60000); // 60秒刷新一次
});

内容的提问来源于stack exchange,提问作者Fraktar

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 08:04:03