Node.normalize () вылетает в IE6 - PullRequest
5 голосов
/ 07 января 2010

Я делаю некоторые манипуляции с TextNodes в JavaScript, и мне (к сожалению) нужно поддерживать IE6. Node.normalize () падает, и мне нужно обойти это. Мое первое желание состоит в том, чтобы просто повторно реализовать его, используя другие методы DOM. Как бы я это реализовал?

Ответы [ 5 ]

7 голосов
/ 13 декабря 2010

Следующая версия короче и эффективнее других, размещенных здесь. Улучшения:

  • Нет повторных вызовов на node.childNodes и node.childNodes.length
  • Нет создания дополнительных текстовых узлов; вместо этого для каждого слияния сохраняйте первый существующий текстовый узел и используйте его appendData() метод
  • 1011 * Короче *

код:

function normalize(node) {
    var child = node.firstChild, nextChild;
    while (child) {
        if (child.nodeType == 3) {
            while ((nextChild = child.nextSibling) && nextChild.nodeType == 3) {
                child.appendData(nextChild.data);
                node.removeChild(nextChild);
            }
        } else {
            normalize(child);
        }
        child = child.nextSibling;
    }
}
5 голосов
/ 21 сентября 2010

Решение, приведенное выше, работало очень медленно и приводило к краху Firefox для меня. Поэтому я немного оптимизировал его, и теперь он отлично работает (основная проблема заключалась в неоднократных ссылках на объект коллекции HTML node.childNodes).

Спасибо за отличную отправную точку, но я решил, что это стоит опубликовать:


function myNormalize(node) {
    for (var i=0, children = node.childNodes, nodeCount = children.length; i<nodeCount; i++) {
        var child = children[i];
        if (child.nodeType == 1) {
            myNormalize(child);
            continue;
        }
        if (child.nodeType != 3) { continue; }
        var next = child.nextSibling;
        if (next == null || next.nodeType != 3) { continue; }
        var combined_text = child.nodeValue + next.nodeValue;
        new_node = node.ownerDocument.createTextNode(combined_text);
        node.insertBefore(new_node, child);
        node.removeChild(child);
        node.removeChild(next);
        i--;
        nodeCount--;
    }
}
1 голос
/ 07 января 2010

Вам необходимо рекурсивно просмотреть все дочерние узлы текущего узла. При рассмотрении узла вы должны удалить любые пустые текстовые узлы и объединить любые смежные текстовые узлы.

 function myNormalize( node )
     for each child node of node do
         if child is not text
            normalize(child)
         else
            if child node is empty
               delete
               continue
            else 
                sibling = next node
                while sibling exists and sibling is a text node
                    if sibling is empty
                       delete sibling
                    else
                       combine sibling with child
                    get next sibling
                end
            end
        end
    end
end
0 голосов
/ 12 сентября 2013

Я думаю, что решение, представленное выше, не совсем правильно. Кстати, вот рабочая функция нормализации плюс функция склеивания, которая использует собственную нормализацию, если она доступна:

function _myNormalizeNode(node) {
if (! node) {
    return;
}

var ELEMENT_NODE = 1;
var TEXT_NODE = 3;
var child = node.firstChild;
while (child) {
    if (child.nodeType == ELEMENT_NODE) {
        this._myNormalizeNode(child);
    }
    else if (child.nodeType == TEXT_NODE) { 
        var next;
        while ((next = child.nextSibling) && next.nodeType == TEXT_NODE) { 
            var value = next.nodeValue;
            if (value != null && value.length) {
                child.nodeValue = child.nodeValue + value;
            }
            node.removeChild(next);
        }
    }
    child = child.nextSibling;
}

}

function  _normalizeNode(node) {
if (! node) {
    return;
}
if (typeof node.normalize == "function") {
    return node.normalize();
}
return _myNormalizeNode(node);

}

0 голосов
/ 07 января 2010

на основе псевдокода tvanfosson, вот что я придумал в javascript:

var ELEMENT_NODE = 1;
var TEXT_NODE = 3;
function normalize(node) {
    for (i=0; i<node.childNodes.length; i++) {
        var child = node.childNodes[i];
        if (child.nodeType == ELEMENT_NODE) {
            normalize(child);
            continue;
        }
        if (child.nodeType != TEXT_NODE) { continue; }
        var next = child.nextSibling;
        if (next == null || next.nodeType != TEXT_NODE) { continue; }
        var combined_text = child.nodeValue + next.nodeValue;
        new_node = node.ownerDocument.createTextNode(combined_text);
        node.insertBefore(new_node, child);
        node.removeChild(child);
        node.removeChild(next);
        i -= 1;
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...