Использование шаблона с пользовательскими элементами HTML
Я только начал изучать пользовательские элементы HTML, и, прочитав серию вступлений, учебных пособий и документации, я думаю, что хорошо разбираюсь в том, как это работает, но у меня есть философский вопрос о том, как правильно использовать или не использовать <template>
тег.
Пользовательские элементы дают вам возможность инкапсулировать новые функциональные возможности, упрощая структуру вашего HTML-документа и позволяя вам просто вставить <my-custom-element>...</my-custom-element>
тег вместо <div class="my-custom-element"><span class="part1">...</span><span class="part2">...</span></div>
,
Определение класса для элемента затем устанавливает структуру и функциональность этого элемента. Затем куча уроков описывает, как использовать <template>...</template>
а также <slot>...</slot>
настроить содержимое пользовательского элемента. Затем вам нужно будет включить код шаблона в каждый документ HTML, в котором вы хотите использовать элемент, а не настраивать его в конструкторе класса пользовательского элемента. Разве это не противоречит тому факту, что пользовательские элементы помогают упростить и инкапсулировать функциональность таким образом, чтобы сделать их более переносимыми? Или я неправильно понимаю правильное использование и / или размещение шаблона в документе?
Просматривая SO, я могу найти следующий ответ на этот вопрос:
Как штамповать шаблон в автономных пользовательских элементах с помощью vanilla js?
Но ответ по существу обходит это все вместе и говорит: "Не используйте <template>
"и так не совсем проясняет мое замешательство.
1 ответ
На самом деле <template>
элементы могут быть импортированы из другого документа через импорт HTML вместе с кодом Javascript, который определит пользовательский элемент:
<link rel="import" src="my-custom-element.html">
...
<custom-element></custom-element>
Поэтому его не нужно включать в каждый HTML-документ. Этот пост показывает минимальный пример.
Импорт HTML реализован только в Chrome и Opera. Если вы хотите использовать их вместе с Firefox и Safari, вам нужно использовать полифилл HTML Imports.
С другой стороны, на данный момент Mozilla и Apple не намерены реализовывать HTML-импорт непосредственно в своих браузерах. Поэтому они рекомендуют определять пользовательские элементы с помощью чистых модулей Javascript (с import
или же <script src="...">
), и вместо этого продвигать строки литералов шаблона, которые предлагают некоторые преимущества (переменные, функции), но иногда более сложны для кодирования в IDE (из-за их строкового представления).
Возможно, в будущем стандартные HTML-модули будут приняты всеми браузерами, и <template>
вернется в центре внимания...
Обратите внимание, что без HTML-импорта вы можете импортировать некоторые HTML-документы с fetch()
:
fetch( "template.html" )
.then( stream => stream.text() )
.then( text =>
customElements.define( "c-e", class extends HTMLElement {
constructor() {
super()
this.attachShadow( { mode: 'open'} )
.innerHTML = text
}
} )
)
Отказ от ответственности: я являюсь автором библиотеки с богатыми компонентами, упомянутой ниже.
После некоторого времени экспериментов с пользовательскими элементами и недавнего создания полномасштабного проекта, основанного исключительно на них, я хотел бы поделиться своими мыслями по этому поводу:
- любой крошечный компонент, как он есть, является кандидатом на превращение в какого-то зверя
- HTML-часть его может разрастаться до такой степени, что будет очень неудобно хранить его в JS.
- сделать шаблон использования, построенный и разобранный один раз и с этой точкой клонированной и впрыскивают в тени корень - это та же самая лучшая практика в отношении использования фрагмента документа вместо мутирует живой DOM
- если содержимое шаблона должно быть изменено от экземпляра компонента к экземпляру - может использоваться какая-то структура привязки данных, и если к ним применяется минималистский подход - все равно может быть проще и эффективнее иметь дело с документом, клонированным из шаблона фрагмент, чем работать со строковыми или шаблонными литералами
Чтобы не писать одни и те же десятки строк снова и снова, я подготовил библиотеку с богатыми компонентами, которая:
- нормализует некоторые API для подготовки шаблонов и все эти строки повторяющегося кода "клонировать шаблон, создавать тень, вставлять в него содержимое шаблона"
- Известно, что извлекает содержимое HTML, когда предоставляется URL-адрес html
- кеширует шаблоны, поэтому выборка выполняется только один раз