如何在AJAX成功回调函数中访问外部`this`并解决绑定报错问题
解决AJAX success回调中访问点击元素
this的问题 首先,你碰到的Uncaught TypeError: Cannot read properties of undefined (reading 'bind')错误,根源很明确:点击事件里的this是触发点击的DOM元素,它本身并没有submit_vote这个方法——submit_vote是你定义的全局函数,所以this.submit_vote自然是undefined,调用bind肯定会报错。
接下来我们一步步修正代码,帮你在AJAX的success回调里顺利访问到最初点击的元素:
方案1:用bind绑定回调的this指向
先修正submit_vote的参数匹配问题(你调用时传了两个参数,但函数只定义了一个),再给success回调绑定指定的this:
// 点击时提交投票 $('.vote-choice-div').on('click', function(event){ event.preventDefault(); // 直接调用全局的submit_vote,传入投票ID和当前点击元素 submit_vote(this.id, this); }); // 修正函数参数,接收投票ID和点击元素两个值 function submit_vote(voteId, clickedElement) { $.ajax({ url : "submit-vote/", headers: {'X-CSRFToken': csrftoken}, type : "POST", data : { vote : voteId }, // 绑定success回调的this为传入的点击元素 success : function(data) { if(data.status === 1){ console.log(this); // 现在这里的this就是最初点击的DOM元素了 // 比如可以直接修改元素样式:this.style.color = '#2ecc71'; } }.bind(clickedElement) }); }
方案2:用ES6箭头函数(更简洁)
箭头函数不会绑定自己的this,它会继承外层作用域的变量,所以我们可以直接在success回调里使用传入的clickedElement:
// 点击时提交投票 $('.vote-choice-div').on('click', function(event){ event.preventDefault(); submit_vote(this.id, this); }); function submit_vote(voteId, clickedElement) { $.ajax({ url : "submit-vote/", headers: {'X-CSRFToken': csrftoken}, type : "POST", data : { vote : voteId }, // 箭头函数直接使用外层的clickedElement变量 success : (data) => { if(data.status === 1){ console.log(clickedElement); // 这里就是最初点击的元素 } } }); }
方案3:利用jQuery AJAX的context配置项
jQuery的$.ajax提供了context选项,可以直接指定所有回调函数里的this指向:
// 点击时提交投票 $('.vote-choice-div').on('click', function(event){ event.preventDefault(); submit_vote(this.id, this); }); function submit_vote(voteId, clickedElement) { $.ajax({ url : "submit-vote/", headers: {'X-CSRFToken': csrftoken}, type : "POST", data : { vote : voteId }, context: clickedElement, // 指定回调的this为点击元素 success : function(data) { if(data.status === 1){ console.log(this); // 这里的this就是点击元素 } } }); }
额外提醒
- 你原来的
submit_vote函数参数定义和调用不匹配,一定要把第二个参数(点击元素)加到函数参数列表里。 - 完全不需要在点击事件里写
this.submit_vote.bind(this)这种代码,因为submit_vote不是DOM元素的方法,直接调用全局函数即可。
内容的提问来源于stack exchange,提问作者JSRB
相关产品推荐
相关产品推荐

