Javascript 已成功覆盖document.getElementsByTagName,但未覆盖Element.prototype.getElementsByTagName

Javascript 已成功覆盖document.getElementsByTagName,但未覆盖Element.prototype.getElementsByTagName,javascript,prototype,Javascript,Prototype,我正在尝试创建一个覆盖getElementsByTagName()方法的程序。为此,我尝试重写document.getElementsByTagName()(案例1)和[x].getElementsByTagName()(案例2),其中[x]是任何DOM元素对象问题:我能够成功覆盖案例1,但无法覆盖案例2 以下是我采用的方法(-我简化了代码,使其更容易理解)。首先,为了涵盖案例1,我重写了document.getElementsByTagName(),因此调用此方法将提醒传递给它的标记名,如下所

我正在尝试创建一个覆盖
getElementsByTagName()
方法的程序。为此,我尝试重写
document.getElementsByTagName()
(案例1)和
[x].getElementsByTagName()
(案例2),其中
[x]
是任何DOM元素对象问题:我能够成功覆盖案例1,但无法覆盖案例2

以下是我采用的方法(-我简化了代码,使其更容易理解)。首先,为了涵盖案例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;
}
//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;
}
接下来,为了处理案例2,我使用了类似的方法覆盖
Element.prototype.getElementsByTagName()
,如下所示:

//Override document.getElementsByTagName
document.oldGetElementsByTagName = document.getElementsByTagName;
document.getElementsByTagName = function(tagName) {
    var theElems = document.oldGetElementsByTagName(tagName);
    alert("The Tag: " + tagName);
    return theElems;
}
//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>
…并警告标记名“
li
”,因此方法重写成功。要测试重写的
元素.prototype.getElementsByTagName()
,执行以下操作

try {
    var items = document.getElementsByTagName("li"); //Will be successful
}
catch (err) {
    alert("Error: " + err.message);
}
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.

元素.prototype.getElementsByTagName()
的重写方法有什么问题?

结果表明,我在重写方法中未正确使用
元素.prototype
。更具体地说,重写方法中的以下代码

var theElems = Element.prototype.oldGetElementsByTagName(tagName);
…应替换为以下内容

var theElems = this.oldGetElementsByTagName(tagName);

请参阅更新的。本质上(如果我理解正确的话),
Element.prototype.oldGetElementsByTagName
只是定义了所有
Element
对象通用的对象
oldGetElementsByTagName
,而不是像在常规函数调用中那样被“调用”(如果这样做,将被解释为对
元素.prototype
对象调用
oldGetElementsByTagName()
).

!为什么要覆盖这些方法?@Bergi我实际上并不是在创建一个web应用程序,而是在任何给定的web应用程序X中创建一个DOM统计跟踪程序,它对DOM方法调用执行动态分析(我显然省略了很多细节,但这是它的要点).我仍处于开发此统计跟踪器的实验阶段,因此我决定首先使用最简单的实现作为概念验证(尽管这个想法可能会在以后发展)。我认为最简单的实现是通过代理向JS代码插入覆盖代码。@Bergi我在过程中遇到了这个问题,并认为分享我找到的解决方案会很有趣。是的,您理解得很正确。可以使用方法语法的替代方法。没错。您也可以尝试
Element.prototype.oldGetElementsByTagName.call(this,tagName)
。顺便说一句,您不需要将旧方法附加到原型上。只需使用一个简单的
var