Это нормально, что JavaScript может создать иначе недействительный DOM?
Несколько случайно я обнаружил, что промежуток, вставленный непосредственно внутри тела, остается на месте, когда выполняется с 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 → остается на месте" между заголовком и первой строкой; исходный, буквенный, диапазон перемещается за пределы таблицы.
Является ли это нормальным, и могу ли/я должен рассчитывать на это? (Он ведет себя одинаково в FF, Chrome, Opera, IE >= 9 (не тестируется ниже)).
Кроме того, есть ли способ запросить DOM, будет ли контент определенного типа (при нормальных обстоятельствах) действительным в определенный момент в DOM? Это на самом деле то, что я хотел сделать, когда узнал об этом причуде (что это, imho).
Скрипка здесь: http://jsfiddle.net/xr37g9kw/2/
Ответы
Ответ 1
Что касается "это нормально, и я могу/должен рассчитывать на это?" К сожалению, да. Но в основном вы должны знать о типах node, с которыми вы работаете. NB, в случае table
существует несколько не очень известных методов DOM (HTMLTableElement.rows. InsertRow() и т.д.).
Что касается "есть ли способ запросить DOM, будет ли контент определенного типа (при нормальных обстоятельствах) действительным в определенной точке DOM?" ничего не было встроено для этой конкретной цели, но вы можете использовать одну собственную функцию JavaScript → DOM API: вы можете позволить браузеру повторно разделить фрагмент HTML "буквально". Да, я говорю о innerHTML.
В вашей скрипте добавление ** tbody.outerHTML = tbody.outerHTML
** "исправляет" структуру, поэтому вы могли гипотетически взять какой-то DOM node, посмотрите на его дерево DOM, клон, "переубедите" его и сравните с оригиналом.
Ответ 2
Да, это поведение по умолчанию, как вы видели. Конечно, он недействителен HTML, так как вы можете проверить здесь http://www.freeformatter.com/html-validator.html, если вы введете HTML.