#javascript #internet-explorer #events #dom #html-table
#javascript #internet-explorer #Мероприятия #dom #html-таблица
Вопрос:
Рассмотрим следующий код JavaScript, предназначенный для создания таблицы 8×8 внутри контейнера div с id="c"
:
//first, two shortcut functions
function $id(a){return(aamp;amp;a.nodeType)?a:document.getElementById(a);}
function $cr8(a){return document.createElement(a);}
//now the meat
var ct = $id('c'),
t = $cr8('table'),
tr, td,
row = 8, cols = 8,
tdclkfn = function () { alert('row: ' this.i ' col: ' this.j); }
for(var i=0;i<row;i ) {
tr = $cr8('tr');
for(var j=0;j<cols;j ) {
td = $cr8('td');
td.i = i;
td.j = j;
td.onclick = tdclkfn;
tr.appendChild(td);
}
t.appendChild(tr);
}
ct.appendChild(t);
Это работает, как ожидалось, в Firefox, Chrome и IE8. Не так много в IE6 / IE7. Как вы можете видеть в этом живом примере, это похоже на то, что разметки таблицы там нет.
Если вы покопаетесь под капотом, используя Firebug Lite или панель инструментов разработчика IE, вы можете обнаружить, что элементы DOM на самом деле там, они просто по какой-то причине не отображаются. Кто-нибудь знает почему?
Я решил посмотреть, что произойдет, если я добавлю ct.innerHTML = '<div/>'
в конец вышеупомянутого JavaScript. Вуаля, оно отображается (смотрите этот обновленный живой пример). Почему это устраняет проблему?
Кроме того, функция, которую я прикрепил к onclick
обработчику событий для каждого <td>
? По-видимому, это вообще не срабатывает. Он прикреплен, вы можете вызвать его с помощью ручного вызова, но щелкнуть по ячейке? Нет, не в IE6 / 7. Почему?
Я знаю, что могу обойти это, используя хорошо управляемый фреймворк JS / DOM, но мне действительно было бы любопытно узнать, что здесь происходит.
Ответ №1:
table
элементы не могут напрямую содержать tr
элементы; IE и другие браузеры с радостью обработают это за вас при разборе разметки (вставляя tbody
автоматически; см. Ниже), но, по-видимому, IE более привередлив, когда вы манипулируете DOM напрямую.
Если вы добавите туда tbody
, IE6 и IE7 будут довольны (отображаются поля, работают обработчики кликов):
var ct = $id('c'),
t = $cr8('table'),
tbody = $cr8('tbody'),
tr, td,
row = 8, cols = 8,
tdclkfn = function () {
alert('row: ' this.i ' col: ' this.j);
}
for(var i=0;i<row;i ) {
tr = $cr8('tr');
for(var j=0;j<cols;j ) {
td = $cr8('td');
td.i = i;
td.j = j;
td.onclick = tdclkfn;
tr.appendChild(td);
}
tbody.appendChild(tr);
}
t.appendChild(tbody);
ct.appendChild(t);
Живая копия (на jsbin.com ; Похоже, мне не очень повезло с IE6 и IE7 и jsfiddle.net ). Ваш исходный код здесь для сравнения на том же сайте.
Что касается автоматической вставки tbody
для вас, вы можете видеть это в действии:
HTML:
<table id='theTable'><tr><td>Test</td></tr></table>
(Примечание № tbody
.)
JavaScript:
window.onload = function() {
var elm, markup;
elm = document.getElementById('theTable');
markup = ["<ol>"];
walk(elm);
markup.push("</ol>");
display(markup.join(""));
function walk(node) {
var child;
markup.push("<li>");
markup.push(node.nodeName);
if (node.nodeType === 1 ||
node.nodeType === 9 ||
node.nodeType === 11) {
markup.push("<ol>");
for (child = node.firstChild;
child;
child = child.nextSibling) {
walk(child);
}
markup.push("</ol>");
}
markup.push("</li>");
}
function display(markup) {
var div = document.createElement('div');
div.innerHTML = markup;
document.body.appendChild(div);
}
};
Вывод:
- ТАБЛИЦА
- TBODY
- TR
- TD
- #текст
- TD
- TR
- TBODY
Обратите tbody
внимание на то, что там есть.
Комментарии:
1. Довольно затянутый TJ, но в конце концов вы добрались туда. 🙂 Суть в том, что при создании таблицы с использованием DOM IE требует явного добавления элемента TBODY, другие браузеры добавят его по умолчанию.
2. @RobG: LOL Ну, я думаю, что вступительный абзац был кратким и по существу. Я просто привел один или два примера… (Кроме того, я точно забыл, что происходит с
tbody
, потому что прошло так много времени с тех пор, как я не включал их явно; поэтому я дважды проверил …)3. Отличный ответ. Также неявно объясняется, почему
ct.innerHTML =
делает вещи видимыми… IE6 / 7 терпимы к свободной разметке (которую мы, по сути, напрямую вставляем здесь).4. @Weston C: Ах, да, я на самом деле не упоминал об этом, не так ли? Но вы были на нем. 🙂 Рад, что помогло,