JS中表单onsubmit事件绑定后仅执行部分代码的原因与解决方法
这个问题的核心是函数执行时this的指向发生了变化,导致后续代码无法正常执行。
为什么两种绑定方式有差异?
1. JS直接绑定事件的情况
当你用workoutform.onsubmit = nameNumberManager.reNameNumberAll;时,你只是把reNameNumberAll函数的引用赋值给了表单的onsubmit属性。当表单触发提交事件时,这个函数是作为表单元素的方法被调用的,此时函数内部的this指向的是触发事件的<form>元素(也就是workoutform),而不是nameNumberManager对象。
这就导致this.getLiftRows()实际上是在调用表单元素的getLiftRows方法——但表单元素根本没有这个方法,代码在这里抛出错误,后续的alert(2)及之后的逻辑自然无法执行。
2. HTML属性绑定的情况
而用onsubmit="return nameNumberManager.reNameNumberAll()"时,函数是通过nameNumberManager对象直接调用的,此时函数内部的this严格指向nameNumberManager,所以所有的方法调用(this.getLiftRows()、this.reNameNumberLiftRows()等)都能正常找到对应的函数,代码可以完整执行。
如何在JS文件中正确绑定事件?
你可以通过以下两种方式修正this的指向,让方法完整执行:
方法1:使用bind()固定this指向
bind()方法会创建一个新函数,将this绑定为你指定的对象:
var workoutform = document.getElementById('workoutform'); workoutform.onsubmit = nameNumberManager.reNameNumberAll.bind(nameNumberManager);
方法2:用匿名函数包裹调用
通过匿名函数手动调用nameNumberManager的方法,确保this指向正确:
var workoutform = document.getElementById('workoutform'); workoutform.onsubmit = function() { // 这里调用时,reNameNumberAll内部的this指向nameNumberManager return nameNumberManager.reNameNumberAll(); };
注意:如果你的
reNameNumberAll方法需要控制表单是否提交,记得让方法返回true(允许提交)或false(阻止提交),就像HTML绑定里的return那样。
内容的提问来源于stack exchange,提问作者Sahand

