我试图创建一个覆盖getElementsByTagName()
方法的程序。为此,我试图覆盖document.getElementsByTagName()
(案例1)和[x].getElementsByTagName()
(案例2),其中[x]
是任何DOM元素对象。 问题:我能够成功覆盖案例1,但不是案例2。成功覆盖document.getElementsByTagName,但不是Element.prototype.getElementsByTagName
下面是我采取的方法(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()
?
[不要乱搞DOM](http://perfectionkills.com/whats-wrong-with-extending-the-dom/)!你为什么要覆盖这些方法? – Bergi
@Bergi我实际上并没有创建一个Web应用程序,而是在任何给定的Web应用程序X中执行DOM方法调用的动态分析的DOM统计信息跟踪器(我显然忽略了很多细节,但这是它的要点)。我仍处于开发此统计跟踪器的实验阶段,所以我决定首先使用最简单的实现作为概念证明(尽管这个想法可能会在以后发展)。我认为最简单的实现是通过代理用重写代码来对JS代码进行测试。 –
@Bergi我一路遇到这个问题,并认为分享我找到的解决方案会很有趣。 –