Веб-основы, CustomElement с shadowDOM и HTML-шаблоны с импортом HTML
У меня есть различные вопросы о реализации веб-основ, я прочитал, что настоящий веб-компонент должен иметь shadowDOM для инкапсуляции CSS, customElements для логики компонента, который я действительно люблю, и HTML-карты и импорт, поэтому я пытаюсь сделать все это в компонент customElement, и я столкнулся со многими и многими проблемами, которые мне трудно отладить, я перечислю их все.
- Нужно ли вставлять HTML-шаблон в документ, чтобы получить его? я не могу получить его содержимое только от js? и в случае, если мне нужно, когда я собираюсь заменить контент shadowHost, как это работает, я имею в виду, что я получил шаблон (ссылку) внутри shadowRoot, моя проблема в том, что когда я делаю
querySelector(
ссылка [отн = "импорт"]).import.querySelector("template")
его нуль после тега функции.import и когда я вставляю эту функцию в документ, он фактически получает содержимое шаблона, вот документ.
Смотря на скриншот, я получил еще 2 вопроса
Должен ли я использовать
shadowHost.innerHTML = file.querySelector(link[rel="import"]).import.querySelector("template")
использовать тег и скопировать его содержимое внутри элемента shadowRoot? Я имею в виду, как я могу реализовать этот подход? Я использую Angular в качестве первого примера, они используют HTML-файл (который предполагает, что это шаблон или тег слота), а затем добавляют его в компонент в качестве параметров конструктора, так как с помощью HTML Templates и HTMLImport я могу реализовать это поведение, я использовали документированные функции, но это не работает на заключительном этапе.Должен ли я сохранить
<link rel="import">
внутри shadowRoot или внутри document.head? Могу ли я реализовать шаблон без необходимости добавления его в документ?
В течение нескольких дней я пытался сделать простой customElement с shadowDOM, который работает полностью нормально, проблема в том, когда я пытаюсь добавить внешний, чтобы сделать его более устойчивым.
Любая помогает? предложения? Я могу показать некоторые функции, которые я использую на компонентах, чтобы иметь представление.
class EgHeader extends HTMLElement {
constructor() {
super();
this.shadowHost = shadowHost.bind(this);
this.shadowStyle = shadowStyle.bind(this);
this.shadowTemplate = shadowTemplate.bind(this);
this.host = this.shadowHost();
}
connectedCallback() {
this.defaultProperties();
let importSelector = this.host.querySelector(`link[rel="import"]`);
console.log(importSelector);
// this.host.appendChild(importSelector.cloneNode(true));
this.host.innerHTML = importSelector.import.querySelector(
"template"
).content;
}
defaultProperties() {
this.getAttributeNames().forEach(key => {
console.log(key);
if (key === "css") {
return this.shadowStyle(this.getAttribute(key));
}
if (key === "template") {
return this.shadowTemplate(this.getAttribute(key));
}
});
}
}
customElements.define("eg-header", EgHeader);
function shadowHost() {
let root = this.attachShadow({
mode: "open"
});
return root;
}
function shadowStyle(stylesheet) {
let link = document.createElement("link");
link.rel = "stylesheet";
link.href = stylesheet + ".css";
this.host.appendChild(link.cloneNode(true));
return link;
}
function shadowTemplate(link) {
var template = document.createElement("link");
template.rel = "import";
template.id = `${link}-template`;
template.href = link + ".html";
document.head.appendChild(template);
this.host.appendChild(template);
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<title>Page Title</title>
<meta name="viewport" content="width=device-width, initial-scale=1" />
<script src="./Header.js"></script>
<script src="./index.js"></script>
</head>
<body>
<eg-header css="./Header" template="./Header">
</eg-header>
</body>
</html>
// Separated file called Header.html
<template>
<nav>This is X element</nav>
<script>
console.warn("Executed when the template is activated.");
</script>
</template>
1 ответ
Я прочитал, что настоящий веб-компонент должен иметь shadowDOM для инкапсуляции CSS, customElements для логики компонента, который я действительно люблю, и HTML Temapltes и импорт
То, что вы прочитали, довольно устарело:
- Импорт HTML устарел, поэтому вы должны использовать другой метод для загрузки шаблонов.
- Из-за #1, шаблоны HTML (иначе
<template>
элементы) часто заменяются шаблонными литералами.
Шаблоны литералов можно определить в Javascript. Таким образом, они могут быть определены в классическом файле Javascript или в модуле ES6.
Кстати, если вы все еще хотите использовать импорт HTML (не рекомендуется), вам нужно использовать полифилл.
<link rel="import">
следует положить в <head>
элемент основного документа, а не в Shadow DOM.
Если вы хотите использовать <template>
вам не нужно добавлять его в основной документ.
var template = document.createElement( 'template' )
template.innerHTML = `
<h1>Title</h1>
<div>Content</div>
`
...
this.shadowRoot.appendChild( template.content.clone( true ) )