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

如何使用Node.js与Handlebars实现博客申请按钮截止后自动禁用

原代码问题排查

你目前的代码核心问题是混淆了前后端代码的执行边界:

  • Node.js 后端路由中写的document.getElementById属于浏览器端API,在服务端完全无法执行,你定义的showButton函数既没有调用也没有传递给模板,模板中判断用的showButton变量根本不存在
  • GET请求的req.body是空的,你无法从这里拿到每个帖子的dateToApply字段,判断逻辑需要针对每一个单独的帖子处理,而不是全局判断一次

正确实现步骤

1. 改造后端路由逻辑

删掉路由中你写的dateNow、applyDate、button、showButton相关无效代码,在查询到帖子列表后,给每个帖子新增标记申请状态的字段再传给模板:

router.get('/', (req, res)=>{
    const perPage = 10;
    const page = req.query.page || 1;

    Post.find({})
        .sort({date: 'desc'})
        .skip((perPage*page)-perPage)
        .limit(perPage)
        .then(posts => {
            const currentTime = Date.now()
            // 遍历处理每个帖子的申请状态
            const processedPosts = posts.map(post => {
                const postPlain = post.toObject()
                // 规则:没设置截止日期默认可申请,设置了的话当前时间小于截止时间可申请
                postPlain.canApply = postPlain.dateToApply ? currentTime < postPlain.dateToApply.getTime() : true
                return postPlain
            })
            Post.count().then(postCount=>{
                Category.find({}).then(categories => {
                    res.render('home/index', {
                        posts: processedPosts,
                        categories: categories,
                        current: parseInt(page),
                        pages: Math.ceil(postCount/perPage)
                    });
                });
            });
        });
});

2. 修改Handlebars模板

首先注意循环渲染的元素不要用重复id,把按钮id改成class,再根据canApply字段控制按钮状态:

  • 如果需求是截止后隐藏按钮,修改对应部分为:
{{#if canApply}}
<button class="btn btn-info apply-btn">Apply</button>
{{/if}}
  • 如果需求是截止后禁用按钮(保留显示),修改对应部分为:
<button class="btn btn-info apply-btn" {{#unless canApply}}disabled{{/unless}}>Apply</button>

可选:前端兜底校验(避免服务端和客户端时间差问题)

如果需要更严谨的校验,可以在前端加一层实时判断,模板中给按钮加截止时间的自定义属性:

<button class="btn btn-info apply-btn" data-deadline="{{dateToApply}}" {{#unless canApply}}disabled{{/unless}}>Apply</button>

然后在页面底部加前端JS:

<script>
const now = Date.now()
document.querySelectorAll('.apply-btn').forEach(btn => {
  const deadline = new Date(btn.dataset.deadline).getTime()
  if(!isNaN(deadline) && now > deadline) btn.disabled = true
})
</script>

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 10:24:02