Javascript рекурсия не охватывает все элементы

0

Я построил reqursion с javascript, который должен запускать все элементы HTML-кода и выводит дерево HTML ELEMENTS по их иерархии.

Код html:

<body>
<p id = "asdgadsfgasdf"><h1>as<strong>asdfasdf</strong>dfasdf</h1></p>
<table id = "table1">
        <tr id = "tr1">
        <td id = "try1" style="background-color:green;"><p id="ChosenColor3"> html file1</p></td>
        <tr id = "trNotFounded">
            <td id = "t1"><p id="Choor3"> html file2</p></td>
        </tr>
        </tr>
        <tr  ></tr>
        <tr>
        <td id = "try2"><p id="ch4"> css file</p></td>
        <td><button id="bestRated3" onclick = arrayTest()> ב.מ </button></td>
        <td><button id="submitForm" onclick = submit()> end</button></td>
        </tr>
        <tr>
        <td id = "try6"><h1 id = "Cr5"> text </h1></td>
        <td><h1 id="Chose111">aasdfasdf</h1></td>
        <td><p id = "1234"> hello111   <span>Here is the problem1</span>   <b>  Here     is the problem2</b>hiii</p></td>
        </tr>
    </table>

<p id = "tr5"> hello </p>
</body>

КОД JAVASCRIPT:

var z1 = document.body.childNodes;
var level = "";
getChildsArea(z1);

function getChildsArea(z) {
        if (z.length > 1) {
          for (i=0; i<z.length; i++){
        if (z[i].nodeType == 1) {
            console.log(level + z[i].nodeName + " CLIENT Area: " + z[i].clientWidth*z[i].clientHeight + " ID: " + z[i].getAttribute('id'));
            if ((z[i].childNodes.length == 0) || ((z[i].childNodes.length == 1 && z[i].childNodes[0].nodeType != 1))) {
                continue;
             }

             else{
                   for (k=0; k<z[i].childNodes.length; k++) {
                    if(z[i].childNodes[k].nodeType == 1) console.log(level + "childs: " + z[i].childNodes[k].nodeName
                                             + " ID: " + z[i].childNodes[k].getAttribute('id'));
                    }
                   level = level + "  ";
                   getChildsArea(z[i].childNodes);
                   level = level.substring(0, level.length - 2)
            }
        }   
          }
        }
        else if (z.length == 1 && z[0].nodeType == 1) {
            console.log(level + z[0].nodeName + " CLIENT Area: " + z[0].clientWidth*z[0].clientHeight + " ID: " + z[0].getAttribute('id'));
        }
  }

Выход (по протоколу консоли):

P CLIENT Area: 0 ID: asdgadsfgasdf
H1 CLIENT Area: 49136 ID: null 
childs: STRONG ID: null 
  STRONG CLIENT Area: 0 ID: null 
TABLE CLIENT Area: 83448 ID: table1  
childs: TBODY ID: null  
  TBODY CLIENT Area: 83448 ID: null
  childs: TR ID: tr1  
  childs: TR ID: trNotFounded  
  childs: TR ID: null  
  childs: TR ID: null  
  childs: TR ID: null  
    TR CLIENT Area: 13176 ID: tr1  // THIS ONE IS OK
    childs: TD ID: try1  
      TD CLIENT Area: 1232 ID: try1  
      childs: P ID: ChosenColor3  
        P CLIENT Area: 1080 ID: ChosenColor3  
    TR CLIENT Area: 16470 ID: null // THIS ONE IS OK

   // where are 3 more ??

    childs: TD ID: try2  
    childs: TD ID: null  
    childs: TD ID: null  
      TD CLIENT Area: 1568 ID: try2  
      childs: P ID: ch4  
        P CLIENT Area: 1080 ID: ch4  
      TD CLIENT Area: 3752 ID: null  
      childs: BUTTON ID: bestRated3  
        BUTTON CLIENT Area: 558 ID: bestRated3  
      TD CLIENT Area: 9660 ID: null  
      childs: BUTTON ID: submitForm  
        BUTTON CLIENT Area: 594 ID: submitForm 

ПРОБЛЕМА: не все элементы отображаются в журнале консоли, например, вы можете увидеть элемент "TBODY", в котором есть 5 (TR элементов), но в нем представлено только 2 ребенка. Я уверен, что я пропустил что-то в своем коде, может кто-то помочь? Спасибо, Дорон

Теги:

2 ответа

1

Просто написал вам скрипку. http://jsfiddle.net/ppbjT/1/

Эта рекурсия показывает все элементы. Вставьте свой журнал.

function findAllElements(element){
    spacing+=spaceValue;
    if(element.tagName){
        console.log(spacing+element.tagName+(element.id? ("#"+element.id):"")+element.className? ("."+element.className):""));
        var children =element.childNodes;
        for (var i= 0;i<children.length;i++){
            findAllElements(children[i])
        }
    }
    spacing=spacing.slice(0,-spaceValue.length);    

}

  • 0
    Это почти работает .. проблема в том, что - как вы можете видеть в моем HTML-коде, есть тег TR внутри тега TR, и ваш код выводит оба tr на одном уровне. Я проверил эту проблему с DTD HTML и это является незаконным написанием (TR может содержать только TD или TH). но, как я описал ниже, мой код работает на большом количестве веб-сайтов, некоторые из которых используют нелегальные записи, и я хочу охватить их все ..
  • 0
    если вы откроете инспектор элементов в chrome, in покажет, что мой логгер работает правильно, потому что chrome исправляет эти проблемы автоматически, и нет никакого способа получить первоначальный порядок, в любом случае страница будет отображаться правильно, если вы протестируете в IE 8, он будет выводить данные, как вы хотите, потому что он не имеет функции фиксации
0

Согласно моему комментарию, основная проблема заключается в том, что ваш HTML недопустим... вы не можете иметь вложенные теги <tr></tr>.

Вы также должны убедиться, что атрибуты используют одиночные или двойные кавычки для значения и не имеют пробелов между ними (хотя это не является строго необходимым, это хорошая практика, чтобы войти). Например

onclick = submit()

Следует заменить на

onclick="submit();"

Ещё вопросы

Сообщество Overcoder
Наверх
Меню