首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >and基础,CustomElement与shadowDOM和HTML模板与HTML

and基础,CustomElement与shadowDOM和HTML模板与HTML
EN

Stack Overflow用户
提问于 2019-02-28 04:50:19
回答 1查看 71关注 0票数 0

我对web实现有各种各样的疑问,我读到一个真正的web组件必须有用于css封装的shadowDOM,用于我真正喜欢的组件的逻辑的customElements,以及HTML和导入,所以我试图在一个customElement组件中完成所有这些工作,我遇到了很多我发现很难调试的问题,我将全部加入它们。

  1. 我必须将html模板插入到文档中才能真正得到它吗?我不能只从js获得它的内容吗?如果我必须这样做,当我打算替换一个shadowHost内容时,它是如何工作的,我的意思是我在shadowRoot中得到了模板(链接),我的实际问题是,当我在.import函数标记之后执行它的null操作时,当我将该函数插入文档中时,它实际上获得了模板内容,下面是文档。

看了那张截图,我还有两个问题

  1. 我应该使用shadowHost.innerHTML = file.querySelector(link[rel="import"]).import.querySelector("template")来使用标记并在shadowRoot元素中复制其内容吗?我的意思是,我怎样才能实施这种方法?我使用角作为第一个例子,他们使用一个HTML文件(猜测它是一个模板或插槽标记),然后将它作为构造函数上的参数添加到组件中,那么如何使用HTMLTemplates和HTMLImport来实现这种行为,我已经使用了文档中的函数,但它在最后阶段不能工作。
  2. 我应该将<link rel="import">保存在shadowRoot中还是document.head中?我可以实现模板而不需要将它添加到文档中吗?

几天来,我一直在尝试用shadowDOM做一个简单的shadowDOM,它工作得很好,问题是当我尝试添加一个外部的,以使它更健壮时。

有什么帮助吗?建议?我可以展示我在组件上使用的一些函数,以便有一个想法。

代码语言:javascript
复制
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);
}
代码语言:javascript
复制
<!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>

EN

回答 1

Stack Overflow用户

发布于 2019-02-28 18:41:53

我曾经读过,一个真正的web组件必须有用于css封装的shadowDOM,用于我真正喜欢的组件的逻辑的customElements,以及HTML和导入。

你读到的东西已经很过时了:

  1. HTML导入是不推荐的,因此您应该使用另一种方法来加载模板。
  2. 由于#1,HTML模板(也称为<template>元素)经常被替换为par模板文字。

模板文字可以在Javascript中定义。通过这种方式,可以在经典Javascript文件或ES6模块中定义它们。

顺便说一句,如果您仍然希望使用HTML导入(而不是重新命令),那么您将需要使用一个polyfill。

<link rel="import">应该放在主文档的<head>元素中,而不是在Shadow中。

如果要使用<template>,则不需要将其附加到主文档中。

代码语言:javascript
复制
var template = document.createElement( 'template' )
template.innerHTML = `
    <h1>Title</h1>
    <div>Content</div>
`
...
this.shadowRoot.appendChild( template.content.clone( true ) )
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/54918600

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档