You need to enable JavaScript to run this app. 如何在Ruby on Rails的html.erb中调用JS函数并传递Ruby变量
优惠活动
大模型
产品
解决方案
定价
更多

如何在Ruby on Rails的html.erb中调用JS函数并传递Ruby变量

Rails 活动倒计时实现:JS 传参踩坑与最终方案

原写法的失效原因

  • 内联脚本直接嵌入Ruby变量的写法<%= javascript_tag "dynamicCountdown(@event.date_time)" %>存在核心缺陷:
    • Rails 渲染后输出的JS代码会变成dynamicCountdown(2024-05-20 14:30:00 UTC),这在JS语法里是完全非法的:没有加引号的时间字符串会被解析为多个减号连接的数字表达式,直接触发语法报错
    • 就算手动给值加引号解决了语法问题,原JS中setInterval(dynamicCountdown, 1000)调用函数时根本没有传入参数,函数接收到的eventTime永远是undefined,无法正常计算剩余时间
  • 直接硬塞Ruby值到内联JS的写法,还存在XSS注入风险,不符合安全规范;如果项目开启了严格的内容安全策略(CSP),内联脚本会被直接拦截,无法执行。

最终可落地的实现方案

用HTML标准的自定义data属性传递后端数据,是Rails场景下前后端交互的通用可靠方案,具体分两步实现:

  1. 在erb模板中给DOM元素绑定data属性存储活动时间
    一定要把时间转成UTC的ISO 8601格式,避免不同用户的本地时区导致倒计时计算错乱,示例代码:
    <h3 class="timer" data-event-date="<%= @event.date_time.utc.iso8601 %>"></h3>
    
  2. 修改JS逻辑,从DOM属性读取时间值完成倒计时计算
    调整后的可运行JS代码:
    let countdown;
    const timerEl = document.querySelector(".timer");
    // 从data属性读取标准格式的活动时间值
    const eventTime = timerEl?.dataset.eventDate;
    
    const dynamicCountdown = () => {
      if (!timerEl || !eventTime) return;
    
      const timeRemaining = Date.parse(eventTime) - Date.parse(new Date());
      // 活动时间到点后停止计时
      if (timeRemaining < 0) {
        clearInterval(countdown);
        timerEl.textContent = "活动已开始";
        return;
      }
    
      const hours = Math.floor(timeRemaining / (1000 * 60 * 60) % 24);
      const minutes = Math.floor((timeRemaining / 1000 / 60) % 60);
      const seconds = Math.floor((timeRemaining / 1000) % 60);
    
      const display = `${hours < 10 ? '0' : ''}${hours}:${minutes < 10 ? '0' : ''}${minutes}:${seconds < 10 ? '0' : ''}${seconds}`;
      timerEl.textContent = display;
    }
    
    // 页面加载后立即计算一次初始值,再开启每秒刷新的定时器
    dynamicCountdown();
    countdown = setInterval(dynamicCountdown, 1000);
    
    export { dynamicCountdown }
    

注意:不要直接把未格式化的Ruby Time对象值直接放到data属性或JS代码中,必须通过iso8601、strftime等方法格式化为JS可识别的标准时间字符串,否则会出现解析失败、时区计算错误的问题。

内容的提问来源于stack exchange,提问作者raphael-allard

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.11.12 16:15:09