JavaScript中如何重新触发触发当前调用栈的原始事件?
操作执行前模态框确认并重触发原始事件实现方案
问题根因
原有实现仅执行了submit事件绑定的匿名回调函数,没有触发完整的DOM事件流,也没有执行表单提交的默认行为,因此表单没有真正提交。
实现方案
方案1:基于caller的非标准hack实现(兼容现有写法)
该方案依赖主流浏览器仍支持的已弃用Function.caller特性,通过获取调用栈中事件对象的原始触发目标和事件类型,主动触发对应事件即可实现需求,修正后的sure函数核心代码如下:
var confirmed_sure = false; function sure(input) { if(confirmed_sure) return true; // 模态框DOM拼接逻辑和原有代码一致 var code = "<div id='sure'>"+ "<div id='sure_inner'>"+ input+ "<br style='clear: both;' />"+ "<div id='sure_yes'>OK</div>"+ "<div id='sure_no'>Cancel</div>"+ "</div>"+ "</div>"; jQuery('html').append(jQuery(code)); // 核心修改:获取原始事件的目标元素和事件类型 const event = sure.caller.arguments[0]; const orig_target = event.originalEvent.target; const orig_type = event.originalEvent.type; jQuery('#sure_yes').click(function() { confirmed_sure = true; jQuery('#sure').remove(); // 主动触发原始事件 setTimeout(() => jQuery(orig_target).trigger(orig_type), 1); }); jQuery('#sure_no').click(function() { jQuery('#sure').remove(); confirmed_sure = false; }); return false; }
方案2:标准实现(无弃用API,推荐)
避免使用已弃用的caller特性,改为主动阻止事件默认行为,配合Promise异步判断确认结果,通用代码如下:
// 通用确认函数,返回Promise function sure(input) { return new Promise((resolve) => { const code = `<div id='sure'> <div id='sure_inner'> ${input} <br style='clear: both;' /> <div id='sure_yes'>OK</div> <div id='sure_no'>Cancel</div> </div> </div>`; jQuery('html').append(code); jQuery('#sure_yes').click(() => { jQuery('#sure').remove(); resolve(true); }); jQuery('#sure_no').click(() => { jQuery('#sure').remove(); resolve(false); }); }) } // 绑定事件写法 jQuery('form').submit(async function(e) { // 首次触发先阻止默认提交 e.preventDefault(); const isConfirmed = await sure("Are you sure you want to submit this form?"); if(isConfirmed) { // 确认后解绑当前事件,触发原生提交避免循环 jQuery(this).off('submit').submit(); } });
该方案不依赖任何非标准特性,适配所有现代浏览器,同时支持click、submit等所有事件场景,扩展性更强。
内容的提问来源于stack exchange,提问作者Bing
相关产品推荐
相关产品推荐

