Задайте свой вопрос о JavaScript на нашем форуме

DOM: Работаем со строками и ячейками таблицы

Перед вами стоит задача "препарировать" таблицу. Пройтись по её строкам и ячейкам, что-то удалить, что-то добавить. Зацепившись за элемент table, мы начинаем использовать привычные DOM-свойства и методы: firstChild, createElement, appendChild и др. И вдруг оказывается, что всё работает совсем не так, как представлялось на первый взгляд.

Неправильный подход

Есть простая таблица, с идентификатором "tableId", в которой требуется удалить первую и добавить в конец новую строку:

<table id="tableId">
    <tr>
        <td>row:1, cell:1</td>
        <td>row:1, cell:2</td>
    </tr>
    <tr>
        <td>row:2, cell:1</td>
        <td>row:2, cell:2</td>
    </tr>
</table>

Решим задачу привычными методами, выполнив функцию no():

function no() {
    var table = document.getElementById("tableId");
    // Перейдем к первой строке таблицы
    var tr1 = table.firstChild;
    alert(tr1.nodeName); // В IE и Opera выведет "TBODY", а в Gecko - "#text"
    // Не получилось, идем другим путем
    var allRows = table.getElementsByTagName("tr");
    tr1 = allRows[0];
    // Удаляем первую строку
    tr1.parentNode.removeChild(tr1);
    // Создаем новую строку
    var tr3 = document.createElement("tr");
    tr3.innerHTML = "<td>row:3, cell:1</td><td>row:3, cell:2</td>";
    // Добавляем её в таблицу
    allRows = table.getElementsByTagName("tr");
    tr3 = allRows[0].parentNode.appendChild(tr3); /* Вот здесь совсем интересно
        В IE строка не отобразилась вовсе, т.к. в добавленной строке находятся битые ячейки, без открывающего тега td
        В Gecko добавился только элемент TR, содержащий строку "row:3, cell:1row:3, cell:2" без ячеек
        Только в Опере всё отработало как задумывалось
    */

    // Затираем добавленную строку
    alert("Сейчас произойдет удаление строки");
    tr3.parentNode.removeChild(tr3);
    // Добавляем то, что хотим более корректно, через DOM
    alert("Повторное добавление строки");
    var td3_1 = document.createElement("td");
    td3_1.innerHTML = "row:3, cell:1";
    var td3_2 = document.createElement("td");
    td3_2.innerHTML = "row:3, cell:2";
    tr3 = document.createElement("tr");
    tr3.appendChild(td3_1);
    tr3.appendChild(td3_2);
    allRows = table.getElementsByTagName("tr");
    tr3 = allRows[0].parentNode.appendChild(tr3);
    // УРА!
}

Как видно из комментариев к коде, в итоге задача решена, но не очень гибким (и уж точно некрасивым) способом.

Правильное решение

Пока мы пытаемся найти кроссбраузерные способы работы с элементами таблицы, в DOM2 давно описан удобный интерфейс как раз для решения таких задач. Почему-то в рунете мало материалов на эту тему, так что остановимся более подробно на разборе необходимых свойств и методов:

Interface HTMLTableElement

  • Свойство rows, возвращает коллекцию узлов строк таблицы, readonly.
  • Метод deleteRow принимает в качестве аргумента индекс строки, которая подлежит удалению. Индексация начинается с нуля.
  • Метод insertRow принимает в качестве аргумента индекс строки, перед которой будет вставлена новая строка. Возвращает ссылку на новую вставленную строку.

Также есть свойства и методы для работы с элементами THEAD, TFOOT, TBODY и CAPTION , но из-за нечастого использования останавливаться на них подробно не будем.

Interface HTMLTableRowElement

  • Свойство cells, возвращает коллекцию узлов ячеек для строки, readonly.
  • Метод deleteCell принимает в качестве аргумента индекс ячейки строки, которая подлежит удалению. Индексация начинается с нуля.
  • Метод insertCell принимает в качестве аргумента индекс ячейки, перед которой будет вставлена новая ячейка в строке. Возвращает ссылку на новую вставленную ячейку.

Interface HTMLTableCellElement

  • Свойство cellIndex, возвращает индекс ячейке в строке (от нуля) readonly.

Решим кроссбраузерно поставленную задачу с помощью перечисленных выше свойств и методов:

function yes() {
    var table = document.getElementById("tableId");
    table.deleteRow(0);
    var newrow = table.insertRow(-1);
    newrow.insertCell(-1).innerHTML = "row:3, cell:1";
    newrow.insertCell(-1).innerHTML = "row:3, cell:2";
}

Надеюсь описанный в этой статье интерфейс облегчит вам работу с таблицами в DOM. Удачи!

Александр Бурцев 6 октября 2008

Все права на статью "DOM: Работаем со строками и ячейками таблицы" принадлежат webew.ru.

Комментарии

dwkwa 23 ноября 2008, 12:17 #
сорри, очипятка: Почему-то рунете, не много материалов на эту тему
 
Bur 23 ноября 2008, 22:17 #
Спасибо, fixed.
 
AndyRoot 9 марта 2009, 13:31 #
Здесь способ, который работает и в IE, в Firefox и Opera
 
Bur 10 марта 2009, 11:45 #
В спецификации DOM Level2 описан УДОБНЫЙ интерфейс работы с таблицами/строками/ячейками, поддерживаемый всеми браузерами. О чем, собственно, эта статья и написана. Так зачем изобретать велосипед?
 
 
Rambler's Top100 Flede HTML valid CSS valid