Fetch仅首次生效:动态切换合作伙伴状态功能故障求助
动态切换合作伙伴状态失效问题解决
问题描述
实现动态激活/停用合作伙伴状态功能,状态变更时弹出Bootstrap模态框,使用Fetch实现但仅首次操作有效,后续同一行或其他行操作均失效,需刷新页面才能再次执行。原有代码如下:
// Activation ou désactivation dynamique d'un partenaire //On boucle sur les input document.querySelectorAll(".form-switch-statut-partenaire input").forEach(input => { input.addEventListener("change", () => { //On récupère l'url de la route edit-statut const Url = input.dataset.path; const Modal = document.getElementById('exampleModal') const Footer = Modal.getElementsByClassName('modal-footer')[0].children[1] Footer.addEventListener("click", () => { //On lance la requête ajax fetch(Url, { headers : { } }) .then((response) => { console.log(response); return response.json() }).then(data => { console.log(data) const content = document.querySelector('body'); content.innerHTML = data.content; }).catch((err) => console.log('Erreur : '+ err)); }) }); });
问题原因
- 重复绑定事件:每次触发input的
change事件时,都会给模态框确认按钮新增点击事件监听,多次操作后事件会叠加执行,导致逻辑混乱。 - 全局DOM替换:使用
content.innerHTML = data.content替换整个body内容,会销毁原有DOM元素及已绑定的所有事件监听,新渲染的元素未重新绑定事件,导致后续操作失效。
解决方案
修改代码,避免重复绑定事件,改用局部DOM更新而非全局替换:
// Activation ou désactivation dynamique d'un partenaire let currentStatutUrl = ''; // 仅绑定一次模态框确认按钮的点击事件 document.querySelector('#exampleModal .modal-footer .btn-primary').addEventListener('click', () => { if (!currentStatutUrl) return; fetch(currentStatutUrl, { headers: { 'X-Requested-With': 'XMLHttpRequest' // 标识AJAX请求,后端可据此返回对应格式数据 } }) .then(response => response.json()) .then(data => { // 局部更新对应行的状态元素,而非替换整个页面 const targetInput = document.querySelector(`input[data-path="${currentStatutUrl}"]`); if (targetInput) { // 切换checkbox状态 targetInput.checked = !targetInput.checked; // 同步更新状态文本(可根据页面结构调整选择器) const statusLabel = targetInput.closest('.form-switch-statut-partenaire').querySelector('.status-text'); if (statusLabel) { statusLabel.textContent = targetInput.checked ? 'Activé' : 'Désactivé'; } } // 关闭模态框并重置URL const modal = bootstrap.Modal.getInstance(document.getElementById('exampleModal')); modal.hide(); currentStatutUrl = ''; }) .catch(err => console.log('Erreur : ' + err)); }); // 绑定input的change事件,记录操作URL并打开模态框 document.querySelectorAll(".form-switch-statut-partenaire input").forEach(input => { input.addEventListener("change", () => { currentStatutUrl = input.dataset.path; // 打开模态框 const modal = new bootstrap.Modal(document.getElementById('exampleModal')); modal.show(); // 暂存并还原checkbox状态,等待用户确认后再更新 input.checked = !input.checked; }); });
修改说明
- 将模态框按钮的点击事件仅绑定一次,通过全局变量
currentStatutUrl传递当前操作的请求地址,避免事件叠加。 - 点击input时先记录URL并打开模态框,同时还原checkbox初始状态,防止用户未确认就直接变更状态。
- 请求成功后局部更新对应行的状态元素,保留页面其他元素及事件监听,避免全局DOM替换导致的事件丢失。
- 使用Bootstrap官方模态框API控制显示/隐藏,符合框架规范。
内容的提问来源于stack exchange,提问作者Marine bde
相关产品推荐
相关产品推荐

