如何在index.js中获取并触发Pug模板内的按钮点击事件?
问题:Pug模板内按钮无法触发index.js中的点击事件
问题描述
在Pug模板中定义了带自定义属性的按钮,期望点击时调用index.js文件中的applySubject函数,但点击按钮无任何反应。其他同模板内的按钮可正常工作,项目使用bundle.js打包脚本。
Pug模板相关代码
// ...其他代码省略 section.course p= subject[0].description .subject button.sbt-enroll(subject-data-slug=`${subject[0].slug}` ) enroll script(src='/js/bundle.js')
index.js相关代码
let subjectBtn = document.querySelector(".sbt-enroll"); if (subjectBtn) { subjectBtn.addEventListener("click", (e) => { e.preventDefault(); const { subject } = e.target.dataset; applySubject(subject); }); }
问题排查与解决方案
1. 修正Dataset属性的匹配问题
Pug中定义的subject-data-slug属性,在DOM的dataset对象中会被转换为驼峰命名的subjectDataSlug,而非subject。原代码中解构const { subject } = e.target.dataset;会得到undefined,导致applySubject函数无法接收到正确参数。
修正方式二选一:
- 方式一:修改JS中的dataset获取逻辑
const { subjectDataSlug } = e.target.dataset; applySubject(subjectDataSlug);
- 方式二:修改Pug中的属性命名为标准
data-*格式(更符合规范)
button.sbt-enroll(data-subject-slug=`${subject[0].slug}` ) enroll
对应的JS代码修改为:
const { subjectSlug } = e.target.dataset; applySubject(subjectSlug);
2. 确保脚本在DOM完全加载后执行
如果bundle.js中的代码在DOM未渲染完成时就执行,document.querySelector(".sbt-enroll")会找不到元素,导致事件绑定失败。需将代码包裹在DOMContentLoaded事件监听中:
document.addEventListener('DOMContentLoaded', () => { let subjectBtn = document.querySelector(".sbt-enroll"); if (subjectBtn) { subjectBtn.addEventListener("click", (e) => { e.preventDefault(); // 这里使用修正后的dataset获取逻辑 const { subjectDataSlug } = e.target.dataset; applySubject(subjectDataSlug); }); } });
3. 可选:使用事件委托提升兼容性
如果按钮是动态渲染的(即使当前是静态模板,也能兼容后续动态场景),推荐使用事件委托绑定到父元素:
document.addEventListener('DOMContentLoaded', () => { document.querySelector('.subject').addEventListener('click', (e) => { if (e.target.classList.contains('sbt-enroll')) { e.preventDefault(); const { subjectDataSlug } = e.target.dataset; applySubject(subjectDataSlug); } }); });
内容的提问来源于stack exchange,提问作者piter765
相关产品推荐
相关产品推荐

