У меня есть следующий код, который работает в 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.
Любая справка ценилась бы.
Спасибо.
Неарудно вызвать 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 происходит в одном из прошедших вызовов, которые они будут потеряны. Глядя на объект матча, как правило, лучше. См. Этот вопрос для другой атаки в основном ту же проблему.
Я думаю, это потому, что 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
}
}
}
Попробуйте использовать это вместо:
var stack = [Array().slice.call(document.getElementsByTagName("body")[0].childNodes)]
Есть некоторая фанкинность с IE и прототипами/конструкторами. Я не могу сейчас тестировать на маке.
Больше информации: Разница между Array.slice и Array(). slice