本机document.createElement()
是愚蠢的(它只需要一个标签名称而没有属性)。为什么我不能覆盖它?为什么这不起作用?
var originalFunction = document.createElement;
document.createElement = function(tag, attributes) {
var element = originalFunction(tag);
if (attributes) {
for (var attribute in attributes) {
element.setAttribute(attribute, attributes[attribute]);
}
}
return element;
};
问题是当您尝试替换本机功能时浏览器会爆炸。由于document
不是JavaScript原语,因此您也无法为其创建原型。 WTF。
答案 0 :(得分:10)
据我所知,问题是即使在引用时调用document.createElement()
函数也必须来自文档。所以修改你的代码:
var element = originalFunction.call(document, tag);
答案 1 :(得分:3)
FWIW(信息性):您可以在某些情况下覆盖“本机”方法,至少在某些浏览器中覆盖。 Firefox让我这样做:
document.createElement = function(f) { alert(f); };
然后在调用时按预期执行。但是你的整个代码块都会抛出一个错误,至少是通过Firebug。
哲学上,你应该能够做到这一点。你可以肯定地重新定义Array对象上的方法等。但ECMAScript不包含窗口(DOM)方法,因此它们可能被允许依赖于实现。当然,出于安全原因,它们也是这样。
答案 2 :(得分:3)
为什么不在你自己的函数中使用这个方法 - 按你想要的方式编写它,再也不要再写document.createElement ....
document.create= function(tag, parent, attributes){
tag= document.createElement(tag);
for(var p in attributes){
if(p== 'css') tag.style.cssText= attributes.css;
else if(p== 'text') tag.appendChild(document.createTextNode(attributes.text));
else tag[p]= attributes[p];
}
if(parent) parent.appendChild(tag);
return tag;
}
document.create('p',document.body,{css:'font-style:italic',className:'important',title:'title',
text:'whatever text you like'});
答案 3 :(得分:1)
据我所知,出于安全原因,您无法覆盖原生方法。对于非本地方法,它根本没问题。
答案 4 :(得分:0)
没有办法覆盖它,但如果你不害怕将非常规参数传递给本机函数,你可以做一些黑客攻击。所以关于createElement的事情是它成为XML DOM的一部分,因此你可以创建你想要的任何标记名。如果你将属性作为第一个参数(标记名)的一部分传递,用你的选择的分隔符分隔它们,然后监听DOM的onchange事件,如果你的分隔符出现在任何参数中,这就是诀窍。标记,用适当的标记替换它们,例如使用RegExp。
答案 5 :(得分:0)
JavaScript: Overriding alert()中提到的代理模式应该适用于此。
在jquery文档中提到过,但看起来它实际上并不依赖于jQuery。
答案 6 :(得分:0)
尝试一下。
document.constructor.prototype.createElement = _ => `P for "pwned"`;
console.log(document.createElement("P"));