我正在尝试为NodeList对象定义一个函数。这是代码:
if (!NodeList.prototype.filter){
NodeList.prototype.filter = function(fun /*, thisp*/){
var len = this.length;
if (typeof fun != "function")
throw new TypeError();
var res = new Array();
var thisp = arguments[1];
for (var i = 0; i < len; i++){
if (i in this){
var val = this[i]; // in case fun mutates this
if (fun.call(thisp, val, i, this))
res.push(val);
}
}
return res;
};
}
这适用于Chrome,但不适用于Firefox。当我调用函数时,Firebug说“current_node.childNodes.filter不是函数”:
nodes = current_node.childNodes.filter(filterByClass);
奇怪的是这段代码:
if(typeof NodeList.prototype.filter == 'function')
alert(NodeList.prototype.filter);
在两个浏览器中显示函数的代码。
它正在HTML中使用,它包括在内:
<script type="text/javascript" src="textselection.js"></script>
编辑: Firefox版本是10.0.2和S.O. Ubuntu 11.04
EDIT2: 我忘记了一个重要因素......它正在iframe中使用
答案 0 :(得分:0)
在一帧中对对象原型所做的更改不会反映在其他帧中。您需要在要扩展的每个框架中包含您的脚本NodeList.prototype
。
请记住NodeList === window.NodeList
,并在框架中window !== top
。因此,在一个框架中,window.NodeList !== top.NodeList
。
有趣的是,对于可实例化的对象,如Date
,您仍然可以利用原型,只要您通过首先使用扩展原型引用框架来实例化对象。例如,如果您的父框架将Date
扩展为.format()
方法,则可以从子框架执行以下操作:
var nowString = new parent.Date().format("MM/dd/yyyy h:mm:ss.fff TT");
答案 1 :(得分:0)
这是我今天遇到的一个非常奇怪的怪癖。似乎Firefox和Chrome不喜欢HTMLCollection和NodeList中名为'filter'的函数,尽管这些原型似乎并没有使用该名称。我将自定义函数重命名为'filt',一切都像魅力一样。顺便说一下,Safari对'过滤器'很好。
答案 2 :(得分:0)
这适用于 Firefox 和 Chrome ,而且更简单:
NodeList.prototype.myfilter = Array.prototype.filter;
示例:以获取具有id属性的所有divs
:
document.querySelectorAll("div").myfilter(function(el){return el.id || 0;})
但是,您需要在使用它的每个帧上定义myfilter
。