一个搜索框,回车就刷新页面。表单标签上写了 onsubmit 等于 return false,还是刷。
这种写法在行内属性里是有效的,问题往往出在别处:要么函数没返回值,要么事件是 addEventListener 绑的。
return false 到底做了什么
在 HTML 属性和老式 onclick 绑定里,返回 false 等于同时做两件事:阻止默认行为,阻止事件冒泡。所以它看起来特别好用。
用 addEventListener 绑的回调,返回值会被忽略。想拦默认行为,得显式调用 preventDefault。这是从 jQuery 转原生时最容易踩的坑。
三种拦住的方式,别混用
preventDefault 只拦默认行为,不拦冒泡。stopPropagation 只拦冒泡,不拦默认行为。return false 两个都拦。先想清楚要拦哪个,再选方法。
按钮是 submit 类型时,点它等于提交表单。只想做校验不想提交,把按钮改成 button 类型,或者干脆不用 form。
两个都调用也行,顺序别反。先 preventDefault,再 stopPropagation,否则外层容器可能先收到事件。
几个具体场景
- 校验不通过还提交:函数里只写了 return,没有返回 false。
- jQuery 的 on 里 return false 有效,addEventListener 里无效,两套规则。
- 异步校验:请求还没回来,提交已经走了,得先拦住再手动提交。
- React 的 onSubmit 里用 preventDefault,别指望 return false。
还有一种情况:表单上有多个 submit 按钮,代码只拦了其中一个。点另一个照样提交,看起来就像拦截失效。
调试顺序
在回调第一行打日志,确认进没进。进了还不拦,就是 preventDefault 没写,或者写在了异步回调后面。没进,说明别处也绑了 submit,或者表单被脚本直接提交了。
一句话:老式绑定看返回值,现代绑定看 preventDefault。混着用,问题就藏起来了。