При синтаксическом анализе через DOM получаем все дочерние элементы и значения

#javascript #dom #recursion

#javascript #dom #рекурсия

Вопрос:

Контейнер — это div, в который я добавил немного базового HTML.

Функция debug_log выводит следующее:

Я в прострации!
Я в div!
Я в
р

Что случилось с остальным текстом в теге p («тег aragraph!!»). Я думаю, что я не понимаю, как именно перемещаться по дереву документа. Мне нужна функция, которая проанализирует все дерево документа и вернет все элементы и их значения. Приведенный ниже код является своего рода первым шагом к тому, чтобы просто получить все отображаемые значения.

     container.innerHTML = '<span>I'm in a span! </span><div> I'm in a div! </div><p>I'm in a <span>p</span>aragraph tag!!</p>';

    DEMO.parse_dom(container);



   DEMO.parse_dom = function(ele)
    {
        var child_arr = ele.childNodes;

        for(var i = 0; i < child_arr.length; i  )
        {
            debug_log(child_arr[i].firstChild.nodeValue);
            DEMO.parse_dom(child_arr[i]);
        }
     }
  

Комментарии:

1. Вы просто ищете DOM-версии этих элементов / узлов или их HTML-представление?

Ответ №1:

Обычно при обходе DOM требуется указать начальную точку. Оттуда проверьте, имеет ли начальная точка childNodes . Если это произойдет, выполните цикл по ним и повторите функцию, если они тоже есть childNodes .

Вот некоторый код, который выводится на консоль с использованием DOM-формы этих узлов (я использовал элемент document / HTML в качестве отправной точки). Вам нужно будет выполнить if против, window.console если вы разрешаете не-разработчикам загружать эту страницу / код и использовать console :

 recurseDomChildren(document.documentElement, true);

function recurseDomChildren(start, output)
{
    var nodes;
    if(start.childNodes)
    {
        nodes = start.childNodes;
        loopNodeChildren(nodes, output);
    }
}

function loopNodeChildren(nodes, output)
{
    var node;
    for(var i=0;i<nodes.length;i  )
    {
        node = nodes[i];
        if(output)
        {
            outputNode(node);
        }
        if(node.childNodes)
        {
            recurseDomChildren(node, output);
        }
    }
}

function outputNode(node)
{
    var whitespace = /^s $/g;
    if(node.nodeType === 1)
    {
        console.log("element: "   node.tagName);  
    }else if(node.nodeType === 3)
    {
        //clear whitespace text nodes
        node.data = node.data.replace(whitespace, "");
        if(node.data)
        {
            console.log("text: "   node.data); 
        }  
    }  
}
  

Пример: http://jsfiddle.net/ee5X6 /

Ответ №2:

В

 <p>I'm in a <span>p</span>aragraph tag!!</p>
  

вы запрашиваете первого дочернего элемента, который является текстовым узлом, содержащим «Я в a».
Текст «тег aragraph!!» является третьим дочерним элементом, который не регистрируется.

Любопытно, что последняя строка, содержащая «p», никогда не должна встречаться, потому что элемент span не является прямым дочерним элементом container .

Ответ №3:

Я не уверен, что это то, что вам нужно, или возможно ли это в вашей среде, но jQuery может довольно легко выполнить нечто подобное. Вот краткий пример jQuery, который может сработать.

 <html>
<head>
<script src="INCLUDE JQUERY HERE">
</script>
</head>
<body>
<span>
<span>I'm in a span! </span><div> I'm in a div! </div><p>I'm in a <span>p</span>aragraph tag!!</p>
</span>
<script>
function traverse(elem){
  $(elem).children().each(function(i,e){
    console.log($(e).text());
    traverse($(e));
  });
}

traverse($("body").children().first());
</script>
</body>
<html>
  

Который выдает следующий вывод на консоль:

 I'm in a span! 
I'm in a div! 
I'm in a paragraph tag!!
p
  

Комментарии:

1. Извините, я не убрал `s, когда копировал ваш пример.

2. Здесь действительно нет необходимости в jQuery.