使用Mutation Observer为页面加载后生成的Save按钮绑定点击事件
修正动态生成Save按钮的Mutation Observer绑定问题
页面加载完成后会动态插入包含value为Save的提交按钮的表单块,原代码通过node.value === 'Save'无法检测到目标按钮,原因是新增的DOM节点是整个表单容器,而非单独的按钮元素。
以下是修正后的完整代码:
// DOM就绪执行函数 function ready(fn) { if (document.readyState !== 'loading') { fn(); } else { document.addEventListener('DOMContentLoaded', fn); } } // 按钮点击处理函数 function buttonClickHandler(event) { event.preventDefault(); const form = event.target.form; console.log(form.reportValidity()); if (form.reportValidity()) { sendMessageToTelegram('000000000', '-999999999'); form.submit(); } } // 为动态生成的按钮绑定事件 function addButtonEventListener() { console.log('开始监听按钮节点...'); const observer = new MutationObserver((mutations) => { mutations.forEach((mutation) => { if (mutation.addedNodes) { mutation.addedNodes.forEach((node) => { // 只处理元素节点 if (node.nodeType !== Node.ELEMENT_NODE) return; // 查找当前节点内部的Save按钮 const saveBtn = node.querySelector('input[value="Save"], button[value="Save"]'); if (saveBtn) { saveBtn.addEventListener('click', buttonClickHandler); // 如果不需要监听后续生成的按钮,可取消下面注释断开观察者 // observer.disconnect(); console.log('已绑定Save按钮点击事件'); } // 处理节点是文档片段的情况(如果有) else if (node.nodeType === Node.DOCUMENT_FRAGMENT_NODE) { const fragmentBtn = node.querySelector('input[value="Save"], button[value="Save"]'); if (fragmentBtn) { fragmentBtn.addEventListener('click', buttonClickHandler); // observer.disconnect(); console.log('已绑定Save按钮点击事件'); } } }); } }); }); // 配置观察者:监听子节点变化,包括子树 const observerConfig = { childList: true, subtree: true }; const commentForm = document.querySelector('.comment-wrapper'); if (commentForm) { observer.observe(commentForm, observerConfig); } else { console.error('未找到.comment-wrapper容器'); } } // DOM就绪后启动监听 ready(addButtonEventListener);
关键修改点:
- 新增节点判断:先过滤非元素节点,避免无效遍历
- 内部查找按钮:使用
querySelector在新增的容器节点内部查找目标按钮,适配整个表单块插入的场景 - 兼容文档片段:处理新增节点为文档片段的情况(部分动态插入可能用文档片段)
- 事件函数优化:显式传入
event参数,避免依赖全局event对象,提升代码健壮性 - 可选断开观察者:如果页面只会生成一次Save按钮,可取消注释
observer.disconnect()以停止监听,节省资源
内容的提问来源于stack exchange,提问作者Patoshi パトシ
相关产品推荐
相关产品推荐

