Вывод HTML DOM дерева
posted in JavaScirpt |В предыдущей статье мы запрограммировали две функции: для добавления и удаления ряда таблицы. Но в Safari и Firefox при удалении был небольшой баг. Приходилось дважды кликать на кнопке Delete. Чтобы понять, почему это происходит, нам необходимо увидеть какое дерево DOM строит каждый браузер для нашей таблицы. Можно использовать плагины для браузеров, но сейчас мы напишем свою простую JavaScript функцию, которая будет печатать в браузере дерево DOM.
У нашей функции будет один параметр — ссылку на элемент, а запускать фнкцию будем таким образом:
Также вы должны знать, что у каждого узла есть свойство nodeType. Если nodeType=1, то этот узел является элементом, если узел — текст (и не может иметь дочерние узлы), то nodeType=3
function printDOMTree(Mid) { var i; // для циклов for (i=0;i<Mid.childNodes.length;i++) // пробегаем по всем дочерним узлам элемента if (Mid.childNodes[i].nodeType==1) // если дочерний узел - элемент { document.write('<br />[' + Mid.childNodes[i].nodeName + ']' ); // напишем его имя в виде [ИМЯ] printDOMTree(Mid.childNodes[i]); // и рекурсивно вызовем нашу функцию для него document.write('[/' + Mid.childNodes[i].nodeName + ']' ); // напишем [/ИМЯ] } else if (Mid.childNodes[i].nodeType==3) // если это текст { if (Mid.childNodes[i].nodeValue=='\n') // если текст - символ перевода строки \n { document.write('<br />[text:\\n]<br />' ); } // то выведем его в браузере как \n else { document.write('<br />[text:' + Mid.childNodes[i].nodeValue + ']<br />' ); } // иначе, просто выведем текст узла } }
Теперь попробуйте такой код:
<div id="DOMTree"> <table border="1" cellpadding="5"> <tbody id="myT"> <tr><td>sample 1</td><td>sample text here...</td></tr> <tr><td>sample 2</td><td>sample text here...</td></tr> <tr><td>sample 3</td><td>sample text here...</td></tr> <tr><td>sample 4</td><td>sample text here...</td></tr> <tr><td>sample 5</td><td>sample text here...</td></tr> <tr><td>sample 6</td><td>sample text here...<img src="" /></td></tr> </tbody> </table> </div> <script> printDOMTree(document.getElementById('DOMTree')); </script>
Посмотрите на вывод функции в различных браузерах и вы увидите, что в IE и Opera DOM дерево бкдет подно этому:
[TABLE]
[TBODY]
[TR]
[TD]
[text:sample 1]
[/TD]
[TD]
[text:sample text here…]
[/TD][/TR]
[TR]
[TD]
[text:sample 2]
[/TD]
[TD]
[text:sample text here…]
[/TD][/TR]
но в Firefox:
[TR]
[TD]
[text:sample 1]
[/TD]
[TD]
[text:sample text here…]
[/TD][/TR]
[text:\n]
[TR]
[TD]
[text:sample 2]
[/TD]
[TD]
[text:sample text here…]
[/TD][/TR]
[text:\n]
То етсь тут у нас повылазили текстовые узлы (\n — перевод строки) после каждого <tr>. Именно поэтому, когда мы удаляем последний дочерний узел tbody в IE, мы удаляем элемент tr, но в Firefox мы удаляем текстовый ухел с «\n», а уже второе нажатие на кнопку удаляет tr. Когда мы встявляем новый ряд, мы нигде не используем символы перевода строки, потому добавленые через нашу функцию ряды удаляются и в Firefox одним нажатием.
Если мы изменим код с таблицей на такой:
<div id="DOMTree"><table border="1" cellpadding="5"><tbody id="myT"><tr><td>sample 1</td><td>sample text here...</td></tr><tr><td>sample 2</td><td>sample text here...</td></tr><tr><td>sample 3</td><td>sample text here...</td></tr><tr><td>sample 4</td><td>sample text here...</td></tr><tr><td>sample 5</td><td>sample text here...</td></tr><tr><td>sample 6</td><td>sample text here...<img src="" /></td></tr></tbody></table></div>
тогда никаких проблем не будет. Другое решение — немного пофиксить функцию для удаления ряда. Как это сделать? Завтра напишу, если сами не напишите 🙂