如何使用Nunjucks调用函数?调用jQuery函数报fooName未定义如何解决?
错误原因
你遇到的报错核心是混淆了Nunjucks模板渲染时机和客户端JS执行时机,同时存在作用域问题:
- Nunjucks是编译/服务端渲染阶段执行的模板引擎,你写在
{{ }}里的fooName(test)会在模板渲染时直接执行,此时你的客户端JS还没加载运行,Nunjucks的上下文里根本没有fooName这个函数,自然会报找不到的错误。 - 你想要的是用户点击时触发客户端的
fooName,但当前写法相当于让Nunjucks在渲染时就运行fooName,把返回值塞到onclick属性里,和你的预期完全不符。 - 就算模板渲染逻辑没问题,你用
const把fooName定义在$(document).ready()的回调块级作用域里,全局作用域访问不到,内联onclick事件触发时也找不到这个函数。 - 额外逻辑问题:你在
fooName里打印的是this.name,但你用了箭头函数定义fooName,箭头函数没有独立this,指向的是外层$(document).ready的上下文,不会拿到你预期的参数或元素属性,同时你也没有用到传入的name参数。
修复方案
第一步:修正模板写法
只有需要从Nunjucks上下文输出变量到客户端的时候,才用{{ }}语法,不要把客户端函数调用包在模板插值里:
<!-- 如果test是Nunjucks上下文里的变量,需要渲染到客户端,写法如下:test为字符串要加引号,escape防止注入 --> <a class="btn" onclick="fooName('{{ test | escape }}')" href="#">Click me!</a> <!-- 如果test是客户端变量,直接写就行:onclick="fooName(test)" -->
第二步:修正JS代码
把fooName提到全局作用域可访问,同时修正逻辑问题:
// 直接定义在全局作用域,不要封闭在$(document).ready的回调里 const fooName = (name) => { // 直接用传入的参数name,不要用this.name console.log(name) }; $(document).ready(() => { // 其他需要DOM加载完成后执行的初始化逻辑放这里 });
注意事项
- 不要把客户端运行的JS逻辑写在Nunjucks的
{{ }}插值语法里,插值仅用于输出模板侧的变量/计算结果 - 内联事件(如onclick)能调用的函数必须在全局window作用域下可访问,不能定义在其他函数的私有作用域中
- 如果你需要在事件处理函数里拿到触发事件的DOM元素,不要用箭头函数定义处理函数,改用普通function声明即可拿到对应的this指向
内容的提问来源于stack exchange,提问作者Kate
相关产品推荐
相关产品推荐

