IE只有getElementsByTagName的javascript错误

Rob*_*Rob 7 javascript internet-explorer

我有以下代码在FF/Chrome中工作

var stack = [Array.prototype.slice.call(document.getElementsByTagName("body")[0].childNodes)], nodes, node, parent, text, offset;
while (stack.length) {
    nodes = stack.pop();
    for (var i=0, n=nodes.length; i<n; ++i) {
        node = nodes[i];
        switch (node.nodeType) {
            case Node.ELEMENT_NODE:
                if (node.nodeName.toUpperCase() !== "SCRIPT") {
                    stack.push(Array.prototype.slice.call(node.childNodes));
                }
                break;
            case Node.TEXT_NODE:
                text = node.nodeValue;
                offset = text.indexOf("[test=");
                if (offset >= 0 && text.substr(offset).match(/^(\[test=(\d+)\])/)) {
                    parent = node.parentNode;
                    var before = document.createTextNode(text.substr(0, offset));
                        link = document.createElement("a"),
                        after = document.createTextNode(text.substr(offset + RegExp.$1.length));
                    link.appendChild(document.createTextNode(text.substr(offset, RegExp.$1.length)));
                    link.setAttribute("href", "http://example.com/" + RegExp.$2);
                    parent.insertBefore(after, node);
                    parent.insertBefore(link, after);
                    parent.insertBefore(before, link);
                    parent.removeChild(node);
                    stack.push([after]);
                }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

基本上它的作用是如果它在页面中找到[test = 25]它将它转换为指向example.com/25的链接

在IE中我得到以下错误:第一行预期JScript对象:

var stack = [Array.prototype.slice.call(document.getElementsByTagName("body")[0].childNodes)], nodes, node, parent, text, offset;
Run Code Online (Sandbox Code Playgroud)

IE7和IE8都会发生此错误.

任何帮助,将不胜感激.

谢谢.

bob*_*nce 12

调用属性(或其他各种DOM方法)返回Array.prototype.sliceNodeList对象是不合法的childNodes.

通常,Thing.prototype.method除了一个实例之外,调用任何东西都是不合法的Thing,但是传统上允许的浏览器 - 以及ECMAScript第三版标准要求 - 许多Array.prototype方法的特殊情况,以便可以在任何本机JavaScript对象上调用它们.足够像一个Array.值得注意的是,这意味着它们可以用在arguments物体上,看起来像Array但实际上并非如此.

但是,NodeListDOM中的其他集合对象未定义为本机JavaScript对象; 它们被允许成为"主机对象",它们完全由浏览器而不是语言实现.所有投注都是关闭主机对象...

切片功能是否可以成功应用于主机对象取决于实现.

所以Array.prototype.slice可能不适用于NodeList,并且在版本8之前的IE中,实际上它不会.

如果要创建NodeList的普通数组副本,则必须以长而安全的方式执行此操作:

Array.fromSequence= function(seq) {
    var arr= new Array(seq.length);
    for (var i= seq.length; i-->0;)
        if (i in seq)
            arr[i]= seq[i];
    return arr;
};

var stack = [Array.fromSequence(document.body.childNodes)];
Run Code Online (Sandbox Code Playgroud)

顺便说一句,你可以通过使用使链接器变得更简单textnode.splitText,并且我对使用全局RegExp属性非常谨慎,好像任何意外的正则表达式工作在其中一个干扰调用中发生它们将会丢失.查看匹配对象通常更好.见这个问题在基本相同的问题再次发作.