Это нормально, что JavaScript может создать в противном случае недопустимый DOM?

Несколько случайно я обнаружил, что диапазон, вставленный непосредственно в tbody, остается на месте, когда выполняется с помощью JavaScript (insertBefore), где такой недопустимый DOM, если бы он был создан с использованием литерального HTML, приводил к тому, что диапазон помещается перед всей таблицей.

Я ожидал того же поведения, что и с литералом HTML, или с некоторым исключением DOM.

Например, этот HTML

<table>
    <thead><tr><th>Table Header</th></td></thead>
    <tbody>
        <span>from HTML &rarr; 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 &rarr; 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.

Другие вопросы по тегам