我正在尝试创建一个覆盖getElementsByTagName()
方法的程序。为此,我尝试覆盖document.getElementsByTagName()
(案例1 )和[x].getElementsByTagName()
(案例2 ),其中[x]
是任何DOM元素对象。 问题:我能够成功覆盖案例1 ,但不能案例2 。
这是我采用的方法(JSFiddle - 我简化了代码以便更容易理解)。首先,为了覆盖案例1 ,我覆盖了document.getElementsByTagName()
,以便调用此方法会提醒传递给它的标记名称,如下所示:
//Override document.getElementsByTagName
document.oldGetElementsByTagName = document.getElementsByTagName;
document.getElementsByTagName = function(tagName) {
var theElems = document.oldGetElementsByTagName(tagName);
alert("The Tag: " + tagName);
return theElems;
}
接下来,为了处理案例2 ,我使用了类似的方法来覆盖Element.prototype.getElementsByTagName()
,如下所示:
//Override Element.prototype.getElementsByTagName
Element.prototype.oldGetElementsByTagName = Element.prototype.getElementsByTagName;
Element.prototype.getElementsByTagName = function(tagName) {
var theElems = Element.prototype.oldGetElementsByTagName(tagName);
alert("The Tag: " + tagName);
return theElems;
}
现在,让我们说DOM包含以下内容:
<ul id="something">
<li>1</li>
<li>2</li>
</ul>
要测试被覆盖的document.getElementsByTagName()
,请执行以下操作...
try {
var items = document.getElementsByTagName("li"); //Will be successful
}
catch (err) {
alert("Error: " + err.message);
}
...它会警告标记名称“li
”,因此方法覆盖成功。要测试被覆盖的Element.prototype.getElementsByTagName()
,将执行以下操作...
try {
var wrapper = document.getElementById("something");
var items = wrapper.getElementsByTagName("li"); //Will lead to error
}
catch (err) {
alert("Error: " + err.message);
}
...但是,在这种情况下,会收到以下错误消息:
Error: 'getElementsByTagName' called on an object that does not implement interface Element.
Element.prototype.getElementsByTagName()
的覆盖方法有什么问题?
答案 0 :(得分:1)
事实证明,我在覆盖方法中使用Element.prototype
是不正确的。更具体地说,最重要的方法中的以下代码......
var theElems = Element.prototype.oldGetElementsByTagName(tagName);
......应该替换为以下内容......
var theElems = this.oldGetElementsByTagName(tagName);
查看更新的JSFiddle。从本质上讲(如果我理解正确的话),Element.prototype.oldGetElementsByTagName
只是定义了所有oldGetElementsByTagName
个对象共有的对象Element
,而不是像常规函数调用那样被“调用”(如果你这样做,它将被解释为你在oldGetElementsByTagName()
对象上调用Element.prototype
。