Это нормально, что JavaScript может создать в противном случае недопустимый DOM?
Несколько случайно я обнаружил, что диапазон, вставленный непосредственно в tbody, остается на месте, когда выполняется с помощью JavaScript (insertBefore), где такой недопустимый DOM, если бы он был создан с использованием литерального HTML, приводил к тому, что диапазон помещается перед всей таблицей.
Я ожидал того же поведения, что и с литералом HTML, или с некоторым исключением DOM.
Например, этот HTML
<table>
<thead><tr><th>Table Header</th></td></thead>
<tbody>
<span>from HTML → goes up</span>
<tr><td>Table Contents</td></tr>
</tbody>
</table>
с этим JavaScript:
var span = document.createElement('span'),
tbody = document.querySelector('tbody');
span.innerHTML = 'Created with JS → stays in place';
tbody.insertBefore(span, tbody.querySelector('tr'));
отображает "Создано с помощью JS → остается на месте" между заголовком и первой строкой; оригинальный, буквальный, span выходит за пределы таблицы.
Это нормально, и могу ли я на это рассчитывать? (Он ведет себя одинаково в FF, Chrome, Opera, IE >= 9 (не тестируется ниже)).
Кроме того, есть ли способ запросить DOM, будет ли контент определенного типа (при нормальных обстоятельствах) действительным в определенный момент в DOM? Это на самом деле то, что я хотел сделать, когда я узнал об этой причуде (то есть, imho).
Скрипка здесь: http://jsfiddle.net/xr37g9kw/2/
2 ответа
Что касается "это нормально, и могу ли я на это рассчитывать?" К сожалению, да. Но в основном вы должны знать типы узлов, с которыми вы работаете. NB, в случае table
Есть несколько не очень известных методов DOM (HTMLTableElement.rows. InsertRow() и т. д.).
Что касается "есть ли способ запросить DOM, будет ли содержимое определенного типа (при нормальных обстоятельствах) действительным в определенный момент в DOM?" Ничего встроенного для этой конкретной цели, но вы можете использовать одну нативную функцию JavaScript -> DOM API: вы можете позволить браузеру пересматривать фрагмент HTML "буквальным путем". Да, я говорю о innerHTML.
В вашей скрипке, добавив **tbody.outerHTML = tbody.outerHTML
** "исправляет" структуру, так что вы можете гипотетически взять некоторый DOM-узел, посмотреть на его DOM-дерево, клонировать, "повторно оценить" его и сравнить с исходным.
Да, это поведение по умолчанию, как вы видели. Конечно, это недействительный HTML, так как вы можете проверить здесь http://www.freeformatter.com/html-validator.html если вы вводите HTML.