IE только ошибка JavaScript с getElementsByTagName

У меня есть следующий код, который работает в 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]);
                }
        }
    }
}

В основном то, что это делает, - то, если это находит [test=25] на странице, это преобразовывает его в ссылку, которая указывает на example.com/25

В IE я получаю следующую ошибку: Объект JScript, Ожидаемый на первой строке:

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

Эта ошибка происходит и в IE7 и в IE8.

Любая справка ценилась бы.

Спасибо.

7
задан Rob 27 January 2010 в 00:54
поделиться

3 ответа

Неарудно вызвать Array.Prototype.sliCe на объекте odelist , что возвращено Childnodes свойством (или различными другими методами DOM).

Обычно это не было бы законным звонить вещь. Прототип. Method на что-нибудь, кроме случаев вещь , однако браузеры традиционно разрешены - и стандарт Ecmastcript Third Edition требует - особый случай для многих Marray.Prototype методы, чтобы их можно назвать на любом объекте Native-JavaScript, который достаточно похоже на массив . Это означает, что значит, что они могут быть использованы на аргументах , который выглядит как массив , но на самом деле нет.

Однако NODELIST и другие объекты коллекции в доме не определены, чтобы быть нативными объектами JavaScript; Им разрешено быть «главными объектами», которые полностью реализуются браузером, а не языком. Все ставки выключены для объектов Host ...

, может ли функция среза быть применена к успешному применению к объекту хоста, зависит от реализации.

Итак Array.Prototype.sliCe может не работать для NodeList, а в IE до версии 8, на самом деле, это не будет.

Если вы хотите сделать скопичную копию odelist odelist, вам придется сделать это длинный, но безопасный способ:

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)];

Кстати, вы можете сделать этот связыватель немного проще с помощью Textnode . Splittext , и я был бы очень осторожен по поводу использования глобальных Progexp свойств , как если бы какое-либо неожиданное рабочую силу Regex происходит в одном из прошедших вызовов, которые они будут потеряны. Глядя на объект матча, как правило, лучше. См. Этот вопрос для другой атаки в основном ту же проблему.

12
ответ дан 6 December 2019 в 11:49
поделиться

Я думаю, это потому, что getElementsByTagname возвращает ноделист - не массив (хотя некоторые вещи вроде оператора [] работают в этом так же, как они работают на массивах, они не одно и то же)

Возможно, это можно решить менее сложным способом:

var els = document.body.getElementsByTagName("*");
for (var i=0, numEls=els.length, el; i<numEls; i++){
    el = els.item(i);
    el.normalize();        
    for (var j=0, chs = el.childNodes, numChs=chs.length, ch; j<numChs; j++){
        ch = chs.item(j);
        if (ch.nodeType==Node.TEXT_NODE){
          //you code for replacing text with link goes here
          //ps i suggest using  ch.data instead of ch.nodeValue
        }
    }
}
3
ответ дан 6 December 2019 в 11:49
поделиться

Попробуйте использовать это вместо:

var stack = [Array().slice.call(document.getElementsByTagName("body")[0].childNodes)]

Есть некоторая фанкинность с IE и прототипами/конструкторами. Я не могу сейчас тестировать на маке.

Больше информации: Разница между Array.slice и Array(). slice

2
ответ дан 6 December 2019 в 11:49
поделиться
Другие вопросы по тегам:

Похожие вопросы: