
当页面中同时存在表单 submit 事件和基于 submit 按钮的 click 事件时,若该按钮未正确阻止默认行为或类型设置不当,会意外触发两个事件,造成同一接口被重复调用、success 回调被误执行等问题。
当页面中同时存在表单 submit 事件和基于 submit 按钮的 click 事件时,若该按钮未正确阻止默认行为或类型设置不当,会意外触发两个事件,造成同一接口被重复调用、success 回调被误执行等问题。
在实际开发中,一个常见但容易被忽视的问题是:将 。由于 type="submit" 按钮天然会触发表单的 submit 事件,即使你为其绑定了独立的 click 处理器,只要未显式阻止默认行为,它仍会“穿透”执行表单提交逻辑 —— 这正是你遇到的现象:点击 #test-template 既运行了它的 click 回调,又触发了 #template_informations 的 submit 回调,最终导致两个 AJAX 请求并发发出。
✅ 正确解法一:在 click 事件中调用 event.preventDefault()
这是最直接、兼容性最好的修复方式。确保 #test-template 的 click 处理器明确阻止表单默认提交行为:
$(document).on("click", "#test-template", function(event) {
event.preventDefault(); // ? 关键:阻止表单提交,避免触发 submit 事件
var formData = $("#template_informations").serialize();
$.ajax({
type: "POST",
url: "/marketing/gpnews/template",
data: formData,
success: function(data) {
var test_field = $(".test-field");
var textoHTML = decodeEntities(data.html);
const div = document.createElement('div');
const parser = new DOMParser();
const parsedHTML = parser.parseFromString(textoHTML, 'text/html');
div.appendChild(parsedHTML.documentElement);
test_field.html(div);
}
});
});
⚠️ 注意:event.preventDefault() 必须放在处理逻辑最开始,且仅对当前事件有效;它不会影响其他事件绑定,但能彻底切断“点击 submit 按钮 → 提交表单 → 触发 submit handler”的链路。
✅ 正确解法二:修改按钮类型为 type="button"
语义更清晰、防御性更强的方式是——让按钮“名副其实”。如果该按钮本意不是提交表单,就不要用 type="submit":
<!-- 替换原 <button id="test-template" type="submit">... --> <button id="test-template" type="button">测试模板</button>
此时,无论是否调用 preventDefault(),点击该按钮都不会触发表单 submit 事件,完全解耦两个逻辑。推荐在团队协作或长期维护项目中优先采用此方案。
? 额外建议:验证事件来源(可选增强)
若需进一步保障健壮性(例如防止未来误加其他 submit 按钮),可在 submit 处理器中检查触发源:
$("#template_informations").submit(function(e) {
// 只有非 #test-template 触发时才执行保存逻辑
if (e.originalEvent && e.originalEvent.submitter?.id === "test-template") {
e.preventDefault();
return;
}
e.preventDefault();
var formData = $(this).serialize();
$.ajax({
type: "post",
url: "/marketing/gpnews/template",
data: formData,
dataType: "json",
headers: { 'X-Requested-With': 'XMLHttpRequest' },
success: function(data) {
$(".code").text(data.html);
}
});
});
但注意:e.originalEvent.submitter 在部分旧浏览器中支持有限,生产环境建议以 preventDefault() 或 type="button" 为主方案。
✅ 总结
| 场景 | 推荐方案 | 关键动作 |
|---|---|---|
| 快速修复已有代码 | ✅ event.preventDefault() | 在 #test-template click 中首行添加 |
| 新建/重构页面 | ✅ type="button" | 从语义和行为上杜绝冲突根源 |
| 高要求健壮性 | ? 双重防护 | type="button" + preventDefault()(冗余但安全) |
二者任选其一即可根治问题,无需修改后端或 AJAX 接口设计。核心原则是:让 DOM 元素的行为与其 HTML 属性严格一致,避免隐式副作用。











