zoukankan      html  css  js  c++  java
  • 学习web components

    什么是web componets, 它的出现是为了什么?

    web components旨在提供一套制作可重用的封装性好的自定义元素的标准。

    它包括四部分:

    customElements -- 这是一个基于CustomeElementRegistry类生成的对象,用于注册自定义元素,如customElements.define('my-popup', MyPop), 并返回已注册的自定义元素的信息。经过注册的元素就可以直接在html页面上像普通元素那样使用了,如<my-popup/>

    shadow DOM -- 影子DOM

    HTML template -- HTML模板

    HTML import -- HTML导入  

    customElements.define用于注册自定义元素,那什么是自定义元素呢?

    自定义元素即为一个class,在这个class里添加各种内置的元素并实现一些逻辑。如果想在页面上使用这个自定义元素,需要用CustomElementRegistry 的define来注册一下。

    自定义元素有两种

      1 autonomous custom elements

      extends HTMLElement, 可以通过<popup-info>或doducment.createElement("popup-info")引入到页面

      注册: customElements.define("popup-info", PopupInfo);

      2 customized built-in elements

      继承自基础的html elements,比如div /p/ span等,需要添加is属性来引入到页面,<p is="word-count">或 document.createElement("p", {is:"word-count"})

      注册: customElements.define('expanding-list', ExpandingList, {extends:"ul"});

      很明显的看出来,customize built-in elements注册时,需要提供第三个参数,来表明是继承自谁

    自定义元素的生命用期:

    • connectedCallback:当 custom element首次被插入文档DOM时,被调用。
    • disconnectedCallback:当 custom element从文档DOM中删除时,被调用。
    • adoptedCallback:当 custom element被移动到新的文档时,被调用。
    • attributeChangedCallback: 当 custom element增加、删除、修改自身属性时,被调用。这个回调需要自定义组件提示 static get observedAttributes(){return ['属性名','属性名',...];}。如果在组件还没 append到某元素上,此时setAttribute也会触发该事件。

     这些都可以在自定义元素的class里直接引入来针对不同的阶段进行相应的业务处理。

    Shadow DOM

    它是document node的一种。对保证组件的独立,使其行为、样式、事件等不受外部的影响起关键作用。它给自定义组件里的元素提供了一个隐蔽的分离出来的DOM.

    与Shadow DOM相关的几个术语:

    • shadow host 是一个普通的dom元素,用来安放shdow dom
    • shadow tree dom树
    • shadow boundary shadow dom的边界,表示shadow dom结束,regular dom开始
    • shadow root shadow tree的根

     

    shadow DOM的基本用法

    this.attachShadow({mode:'open'}),将shadow root加到自定义元素上。mode有两个值:open和closed。open的话,在外边也可以访问到组件的shadowRoot,closed的正好相反.

    let myShadowDom = myCustomElem.shadowRoot;
    

     mode为open时myShadowDom可以取到值,并能对里边的元素做操作。mode为close时myShadowDom为null; 

    function updateStyle(elem) {
      const shadow = elem.shadowRoot; // 访问自定义组件的shadow root
      shadow.querySelector('style').textContent = `
        div {
           ${elem.getAttribute('l')}px;
          height: ${elem.getAttribute('l')}px;
          background-color: ${elem.getAttribute('c')};
        }
      `; // shadow root有跟document类似的方法如getElementById,querySelector等
    }
    

      

    slot和template

    在shadow dom中引入slot来增加灵活性。搭配使用template效果更佳。

    slot让用户可给向自定义组件里添加自己的标签元素。它通过name属性来指定一个slot,所以组件内的slot的name要唯一。

    <template>标签里的代码片断(DocumentFragment)不会被rend到页面上,只能通过javascript的Node.cloneNode克隆出新的DocumentFragment然后后再appendChild或是insertBefore来加来到dom树上。

    template里的documentFragment通过HTMLTemplateElement.content来取得。

    <template id="element-details-template">
      <style>
      details {font-family: "Open Sans Light",Helvetica,Arial}
      .name {font-weight: bold; color: #217ac0; font-size: 120%}
      h4 { margin: 10px 0 -8px 0; }
      h4 span { background: #217ac0; padding: 2px 6px 2px 6px }
      h4 span { border: 1px solid #cee9f9; border-radius: 4px }
      h4 span { color: white }
      .attributes { margin-left: 22px; font-size: 90% }
      .attributes p { margin-left: 16px; font-style: italic }
      </style>
      <details>
        <summary>
          <span>
            <code class="name"><<slot name="element-name">NEED NAME</slot>></code>  <!--slot->
            <i class="desc"><slot name="description">NEED DESCRIPTION</slot></i> <!--slot->
          </span>
        </summary>
        <div class="attributes">
          <h4><span>Attributes</span></h4>
          <slot name="attributes"><p>None</p></slot> <!--slot ->
        </div>
      </details>
      <hr>
    </template>
    

      

    customElements.define('element-details',
      class extends HTMLElement {
        constructor() {
          super(); // constructor里先写上super,this才能被赋值
          var template = document
            .getElementById('element-details-template')
            .content;// template可以通过dom的方法来取到,它的content属性返回的就是内部的DocumentFragment
          const shadowRoot = this.attachShadow({mode: 'open'}) // 自定义组件首先要创建shadow,通过appendChild来往shadow里添加标签元素
            .appendChild(template.cloneNode(true));
      }
    })
    

      

    <element-details>
      <span slot="element-name">slot</span> <!--通过给标签添加slot="slotName"来将这个标签填充到自定义标签里->
      <span slot="description">A placeholder inside a web
        component that users can fill with their own markup,
        with the effect of composing different DOM trees
        together.</span>
      <dl slot="attributes"> <!--如果不给名称为attribute的slot写标签的话,会用自定义组件里的该slot内的标签->
        <dt>name</dt>
        <dd>The name of the slot.</dd>
      </dl>
    </element-details>
    

     还有一个与此相关的css伪类:define :host :host-context,方法,可以用到时再学习

    总结

    实现web componets的步骤与方法如下:

    https://developer.mozilla.org/zh-CN/docs/Web/Web_Components

  • 相关阅读:
    函数指针
    指针和数组的关系
    const修饰指针的三种效果
    指针做函数参数 (间接赋值是指针存在的最大意义)
    野指针
    指针
    JSP九大内置对象
    Android--获取App应用程序的大小
    Android--获取标题栏,状态栏,屏幕高度
    Android--获取使用的总流量和每个App的上传、下载的流量
  • 原文地址:https://www.cnblogs.com/Gift/p/10688973.html
Copyright © 2011-2022 走看看