EJS模板onclick事件调用外部JS函数触发逻辑异常求助
问题核心原因
- 混淆了服务端JavaScript执行上下文和客户端浏览器JavaScript执行上下文:你当前将
functions.js通过require导入到服务端server.js中,当EJS模板渲染时,<%= data.function() %>会直接在服务端执行这个函数,你看到的日志实际是服务端终端的输出,并非浏览器控制台的输出。 - EJS模板渲染完成后,按钮的
onclick属性最终会被渲染为onclick="'undefined';"(因为你的optionClick函数没有返回值),点击按钮时自然不会执行任何逻辑。
你之前把函数直接写在main.ejs的script标签中可以正常运行,是因为此时函数是在客户端浏览器的上下文声明的,和直接引入外部JS文件的逻辑一致。
正确实现步骤
- 调整外部JS文件
functions.js(存放在public静态资源目录下),移除服务端CommonJS导出语法,浏览器不识别该语法:
// public/functions.js function optionClick() { console.log("Yoohooo!!"); }
- 确保
server.js已经配置了静态资源托管,同时删除引入functions.js、给模板传递函数的冗余代码:
// server.js 新增配置,放在路由定义之前 app.use(express.static('public')); // 修改后的/question路由 app.get('/question', (req, res) => { // 如果有其他要传给模板的业务数据保留即可,不需要传递函数 res.render('main.ejs', { data: {} }); });
- 修改
main.ejs,先引入客户端可用的外部JS文件,再给按钮绑定点击事件:
<!-- 引入静态资源目录下的外部JS,要放在按钮代码之前,或者body末尾 --> <script src="/functions.js"></script> <!-- 直接绑定客户端上下文中的函数名即可,不需要加EJS模板标签 --> <button id="submit-button" onclick="optionClick()"> START </button>
补充说明
如果你的点击函数需要用到服务端的业务数据,可以通过EJS将数据渲染为客户端可读取的全局变量即可,不需要把函数本身从服务端传递:
<!-- main.ejs 中插入 --> <script> // 将服务端的data数据转为客户端JS变量 const serverData = <%- JSON.stringify(data) %> </script>
内容的提问来源于stack exchange,提问作者F.Mi
相关产品推荐
相关产品推荐

