如何在不使用 Shadow DOM 的情况下创建组件?

How to create a component without using the Shadow DOM?

我正在尝试创建一个没有阴影的组件 DOM。是的,我知道,Shadow DOM 很棒而且是 Web Components 的主要焦点之一。但是,假设我想要一个组件的样式从父级继承。

有阴影DOM

<dom-module id="my-view1">
  <template>
    <div class="card">
      <div class="circle">1</div>
      <h1>View One</h1>
      <p>Ut labores minimum atomorum pro. Laudem tibique ut has.</p>
      <p>Lorem ipsum dolor sit amet, per in nusquam nominavi periculis, sit elit oportere ea.Lorem ipsum dolor sit amet, per in nusquam nominavi periculis, sit elit oportere ea.Cu mei vide viris gloriatur, at populo eripuit sit.</p>
    </div>
  </template>
  <script>
    class MyView1 extends Polymer.Element {
      static get is() { return 'my-view1'; }
    }
    window.customElements.define(MyView1.is, MyView1);
  </script>
</dom-module>

我已应用 Polymer 组提供的说明,不使用阴影 DOM,地址:https://developers.google.com/web/fundamentals/getting-started/primers/shadowdom

但是,如果我不指定 template 或指定 static get template() { return false; },DOM 甚至不会加载自定义组件中的元素。

你想达到什么目的?

例如,您为此扩展了 Polymer 元素甚至 HTMLElement。

  • 如果超级元素有一个模板,则子元素将继承该模板,除非您将其指定为 NOT 或 return false 来自子元素中的 template getter.

  • 如果父元素没有指定模板,则您不会继承模板。

也就是说,

如果你想创建一个没有 template/shadowDOM 的自定义元素,

必须定义它的属性、属性和行为(如果有的话)。

这段代码绝对给你创造一个元素没有一个影子DOM如你所愿

class myApp extends Polymer.Element{
   constructor(){
     super();
   }
   connectedCallback(){ 
    super.connectedCallback();
   }
   static get template(){
    return false;
    // Or, Memoized template
    // Read Docs from link below 
   }
   //Also, define properties , observers, behaviors as per your whim
}

由于浏览器根本不知道如何绘制/布局您的自定义元素,您需要为其配备阴影 DOM / 通过 JS 自定义模板

如果没有阴影树scope/distribute,你显然不能强迫它渲染光DOM 你自然不能指望它在没有模板的情况下渲染任何东西。

所以,当你说,

But, if I were to not specify a template or specify static get template() { return false; }, the DOM doesn't even load the elements in the Custom Component.

templatingshadowDOM 的上下文中应该很明显,如果你正在创建一个没有 shadow DOMtemplate 的元素,你只需不能期望它呈现任何内容,self/distributed

此外,

如果从父元素继承行为是您的objective,

并在不渲染父模板中的内容的情况下执行此操作,和/或仅使用父模板中的位

Polymer 中,您可以使用 memoizing 跳过父模板中的内容 阅读 here

如您所说,如您所知:

"Yeah, I know, Shadow DOM is great and all and is one of the main focuses of Web Components."

您使用了 inherit 这个词,而阴影-dom 的一大优点是继承的文本样式会泄漏到阴影中..

例如:

<style>
  p { font-size: 1.3em }
</style>
<p><your-element></your-element></p>

如果您没有覆盖 your-element 中的文本样式,它们将继承 font-size 属性 外部样式。

如果您真的想在元素之间共享样式,我们在 dom 模块模板中为 style 标签使用 include 属性。例如,

<dom-module id="french-fries-styles">
  <template>
    <style>
      .french-fries {
        display: block;
        width: 100px;
        height: 30px;
        background-color: yellow; /* french fries are yellow */
      }
    </style>
  </template>
</dom-module>

<dom-module id="french-fries-are-tasty">
  <style include="french-fries-styles"></style>
  <div class="french-fries"></div>
</dom-module>

<dom-module id="burger-king">
  <style include="french-fries-styles"></style>
  <div id="burger-king-fries" class="french-fries"></div>
</dom-module>

Shadow dom 是一个伟大的概念,我们应该尝试采用它,但仍然需要使用旧库,我们可以放弃它。这些库主要使用 light dom。使用聚合物 2 元素,您可以通过覆盖 Polymer.ElementMixin_attachDom 方法来附加到光 dom 这里是一个例子.

class MyElement extends Polymer.Element {

    static get is() { return 'my-element'; }

    static get template() { return `<h1>My element</hi><div><slot><slot></div>`; }

    _attachDom(dom) {
        Polymer.dom(this).appendChild(dom);
    }
}

window.customElements.define(MyElement.is, MyElement);

这会将元素附加到元素的灯光 dom 上。您可以根据需要将元素附加到文档中的任何位置。