如何默认将Button元素type设为button?解决非法调用异常
你遇到的「illegal invocation」错误原因很明确:document.createElement是绑定在document上的原生方法,调用时必须以document作为上下文(也就是this指向)。你原代码里把它赋值给createE后直接调用,此时this指向全局对象(浏览器环境下是window),浏览器不允许这种非法调用原生方法的行为,所以抛出异常。另外原代码还漏掉了返回创建好的元素,就算不报错,调用document.createElement也拿不到结果。
下面给你两个可行的实现方案:
方案1:正确重写document.createElement
用普通函数代替箭头函数,调用原方法时通过call绑定document作为上下文,同时记得返回元素:
// 保存原生方法的引用 const originalCreateElement = document.createElement; // 重写createElement方法 document.createElement = function(tagName) { // 绑定document上下文调用原生方法 const elem = originalCreateElement.call(this, tagName); // 对button元素设置默认type属性 if (tagName.toLowerCase() === 'button') { elem.type = 'button'; } // 返回创建完成的元素 return elem; };
方案2:用MutationObserver监听DOM新增元素
如果不想修改原生API的行为,可以通过监听DOM变化来实现,当页面中新增button元素时自动补全type属性:
const observer = new MutationObserver((mutations) => { mutations.forEach(mutation => { // 遍历所有新增的节点 mutation.addedNodes.forEach(node => { // 判断是button元素且未设置type时赋值 if (node.tagName?.toLowerCase() === 'button' && !node.type) { node.type = 'button'; } }); }); }); // 监听整个文档的子节点变化,包括所有嵌套子树 observer.observe(document.documentElement, { childList: true, subtree: true });
两个方案各有侧重:方案1是在元素创建阶段直接处理,效率更高;方案2是被动监听DOM变化,不会改动原生方法的原有逻辑,适合对原生API修改有顾虑的场景。
内容的提问来源于stack exchange,提问作者ControlAltDel
相关产品推荐
相关产品推荐

