如何阻止函数被多次调用?日历删除事件重复触发弹窗问题
问题根因
- 重复绑定事件监听器:你每次点击事件条目触发
delete_event函数时,都会给删除确认按钮.delTrue新增一次event_del_true的点击监听,操作多少次就绑定多少个回调。点击确认删除时所有绑定的回调会同步执行,所以Toast弹窗次数随操作次数递增。 - 事件条目绑定逻辑错误:你在遍历事件条目绑定监听的循环里加了
break,只会给第一个.eventEntry元素绑定点击事件,后续的事件条目点击不会触发删除流程。
修复方案
核心调整逻辑
把删除确认按钮的监听绑定从delete_event函数中移出来,全局仅绑定一次,用全局变量存储当前要删除的事件ID即可,避免重复绑定。
完整修改后代码
// 全局存储当前待删除的事件ID let currentDelEventId = ''; // 页面初始化时仅绑定一次删除确认按钮的点击事件 document.querySelector('.delTrue').addEventListener('click', event_del_true, false); // 给所有事件条目绑定点击事件,移除多余的break const delEvent = document.getElementsByClassName('eventEntry'); for (let e = 0; e < delEvent.length; e++) { delEvent[e].addEventListener('click', delete_event, false); } // 打开删除确认模态框,仅做ID赋值和模态框唤起操作 function delete_event(d){ currentDelEventId = d.currentTarget.id; $('#modal-delete').modal('open'); } // 实际删除逻辑,使用全局存储的待删除ID function event_del_true(){ $.ajax({ type: "POST", url: "php/delete-event.php", data: {id: currentDelEventId} }).done(function() { M.toast({ html: '事件已删除', classes: 'rounded', displayLength: 2000, inDuration: 375, outDuration: 300 }); }); }
优化建议(可选)
如果你的事件条目是切换日期时动态渲染的,推荐用事件委托实现,不需要每次渲染完重新绑定监听:
// 给事件条目的固定父容器绑定委托事件,示例父容器class为calendar-day-content document.querySelector('.calendar-day-content').addEventListener('click', function(e) { if (e.target.classList.contains('eventEntry')) { currentDelEventId = e.target.id; $('#modal-delete').modal('open'); } }, false);
内容的提问来源于stack exchange,提问作者Dannyboy
相关产品推荐
相关产品推荐

