Рассмотрим:
<template>
<style>
body: { background-color: black; }
</style>
<script>
alert('hello');
</script>
<audio src="alert.wav" autoplay></audio>
</template>
И
<div style="display: none;">
<style>
body: { background-color: black; }
</style>
<script>
alert('hello');
</script>
<audio src="alert.wav" autoplay></audio>
</div>
Будут ли они вести себя одинаково, когда их отображает браузер? (Спойлер: нет.)
Чтобы ответить на ваши конкретные вопросы, хотя:
- На низком уровне, как браузер по-разному обрабатывает эти 2 примера?
Например, HTML внутри <template>
не становится элементами DOM, которые являются потомками <template>
. Он становится потомком «инертного» DocumentFragment (косвенно; это упрощение), где они существуют как узлы, но ничего не «делают», как в примере выше.
Помимо «инертности», содержимое шаблона не имеет «требований соответствия». Ваш <tr>
пример выше - хороший. Посмотрите, что здесь происходит:
const template = document.querySelector('template');
const div = document.querySelector('div');
console.log('template.innerHTML is', template.innerHTML);
console.log('div.innerHTML is', div.innerHTML);
<template>
<tr>
<td class="record"></td>
<td></td>
</tr>
</template>
<div style="display: none">
<tr>
<td class="record"></td>
<td></td>
</tr>
</div>
В обычном документе <tr>
не может быть дочерним по отношению к <div>
, поэтому браузер просто удаляет его. В <template>
это требование не существует. Вы найдете то же самое с, скажем, <div style="{{myStyle}}">
. В документе браузер отбрасывает атрибут style
, поскольку его значение недопустимо; в <template>
не было бы. Вот что делает <template>
полезным для шаблонов.
Если вы хотите узнать больше о том, как визуализируются <template>
s, я предлагаю прочитать раздел об этом в спецификации HTML . Это не легко читать, и части могут быть непонятны, но вы многому научитесь.
- Некоторые методы JS или атрибуты HTML отличаются или недоступны?
Элемент <template>
имеет атрибут content
, который указывает на фрагмент документа, рассмотренный выше.