Ванильная структура веб-компонента
Я смотрю на структурирование ванильных веб-компонентов. Ранее я использовал Polymer, и мне нравится тот факт, что вы можете иметь шаблон, стили и JavaScript в одном файле для вашего компонента. Я хочу достичь этого с помощью "ванильных" веб-компонентов, если это возможно, но не могу понять, как. Я взял код отсюда и добавил его в файл, который я использую следующим образом:
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Component test</title>
<link rel="import" href="x-foo-from-template.html">
</head>
<body>
<x-foo-from-template></x-foo-from-template>
</body>
</html>
Это терпит неудачу, потому что, когда мы пытаемся выбрать шаблон, он не существует, потому что в этот момент шаблон не находится в DOM (правильно?).
Есть ли способ добиться этого? Я лично предпочитаю такой подход к созданию HTML в JavaScript с помощью document.createElement
,
2 ответа
Есть 2 основных способа получить шаблон из импортированного документа:
1. Из import
собственность <link>
элемент
<link rel=import>
элементы владеют import
свойство, которое содержит импортированный документ. Вы можете выполнить querySelector
позвони, чтобы получить <template>
:
var doc = document.querySelector( 'link[href$="x-foo-from-template.html"]').import
var template = doc.querySelector( 'template' )
Затем импортируйте шаблон в пользовательский элемент (или в его Shadow DOM), используя importNode()
или же cloneNode()
,
2. Сформируйте ownerDocument
собственностью currentScript
Когда скрипт анализируется, глобальное значение document.currentScript
ссылается на анализируемый скрипт, и, следовательно, его свойства ownerDocument
ссылка на документ, которому принадлежит скрипт Вы можете выполнить querySelector
позвони на это:
var template = document.currentScript.ownerDocument.querySelector( 'template' )
Примечание: currentScript
значение устанавливается временно, поэтому оно не будет работать больше при последующих вызовах, например connectedCallback()
или же attachedCallback()
Таким образом, вам придется запомнить его в постоянной переменной во время разбора, чтобы использовать его позже при необходимости.
Для опоздавших:
С 2021 года функция импорта HTML устарела (MDN Link).
Я бы не рекомендовал это, вместо этого вы можете: создать тег шаблона с атрибутом data- для импорта html. Напишите сценарий, который запускается для всех этих элементов с этим атрибутом, и получите доступ к этим частям html, используя
fetch()
в скрипте добавьте полученный импорт в тег шаблона и используйте его, например:
template.content.cloneNode( true )
.