自定义元素 v1:可重用网络组件

google文档 https://developers.google.cn/web/fundamentals/web-components/customelements

兼容性 https://caniuse.com/#search=custom

shadow DOM https://developers.google.cn/web/fundamentals/web-components/shadowdom

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>自定义组件</title>
  <style>
    ajanuw-title {
      font-family: 'Consolas';
      color: rgba(255, 68, 136, 1);
      font-size: 22px;
      display: block;
    }
  </style>
</head>

<body>
  <div id="root">
    <ajanuw-title a-title="hello alone"></ajanuw-title>

    <ajanuw-title a-title="hello ajanuw"></ajanuw-title>
    
    <ajanuw-title>
        <strong slot="last-slot">go go go ..</strong>
    </ajanuw-title>

    <ajanuw-title>
      <strong slot="inter-slot">go go go ..</strong>
    </ajanuw-title>

    <button is="ajanuw-button">click me</button>
    <div class="btn">

    </div>
  </div>
  <template id="shadow-template">
    <style>
      em {
        contain: content;
        font-family: Monaco, Consolase;
        padding: 4px;
      }
    </style>
    <!-- 模板是声明自定义元素结构的理想之选。 -->
    <em>I'm in shadow dom!</em>
    <slot name="inter-slot">[[default inner slot]]</slot>
    <en>from template</en>
    <slot name="last-slot">[[default last slot]]</slot>
  </template>
  <script>
    class ajanuwTitle extends HTMLElement {
      static get observedAttributes() {
        return ['active'];
      }
      // 自定义元素
      constructor(prop) {
        // 创建或升级元素的一个实例。用于初始化状态、设置事件侦听器或创建 Shadow DOM
        super(prop);
        // this.setAttribute('title', '自定义组件')
        this.addEventListener('pointerover', e => this.setAttribute('active', ''), false);
        this.addEventListener('pointerout', e => this.removeAttribute('active'), false);
      }
      fadeOut() {
        this.style.opacity = '.7';
      }
      fadeIn() {
        this.style.opacity = '1';
      }

      get isActive() {
        return this.hasAttribute('active');
      }
      connectedCallback() {
        // `元素每次插入到 DOM 时都会调用`
        if (this.hasAttribute('a-title')) {
          this.textContent = this.getAttribute('a-title');
        } else {
          let shadowRoot = this.attachShadow({
            mode: 'open'
          });
          const t = document.querySelector('#shadow-template');
          const instance = t.content.cloneNode(true);
          // shadowRoot.appendChild(instance);
          shadowRoot.append(instance)
        }
      }
      disconnectedCallback() {
        // `元素每次从 DOM 中移除时都会调用。用于运行清理代码(例如移除事件侦听器等).`

      }
      attributeChangedCallback(name, oldVal, newVal) {
        // `属性添加、移除、更新或替换。解析器创建元素时,或者升级时,也会调用它来获取初始值。`
        // `注:仅 observedAttributes 属性中列出的特性才会收到此回调`
        if (this.isActive) {
          this.fadeOut();
        } else {
          this.fadeIn();
        }

      }
      adoptedCallback() {
        // `自定义元素被移入新的 document(例如,有人调用了 document.adoptNode(el).`

      }
    }
    window.customElements.define('ajanuw-title', ajanuwTitle);

    customElements.whenDefined('ajanuw-title').then(() => {
      // `浏览器会因为存在未知标记而采用不同方式处理潜在自定义元素。调用 define() 并将类定义赋予现有元素的过程称为“元素升级”。`
      console.log('ajanuw-title defined');
    });

    // `返回元素的构造函数。如果没有注册元素定义,则返回 undefinedF`
    let ATitle = customElements.get('ajanuw-title');
    let atitle = new ATitle();
    // console.log(ATitle);


    class ajanuwButton extends HTMLButtonElement {
      // 拓展元素
      constructor(prop) {

        super(prop);

        this.addEventListener('pointerover', e => {
          console.log(1);
          this.style.boxShadow = '2px 2px 10px #f48';
        }, false)
      }
    }

    window.customElements.define('ajanuw-button', ajanuwButton, {
      extends: 'button'
    });

    let button = document.createElement('button', {
      is: 'ajanuw-button'
    });
    button.textContent = 'Fancy button!';
    document.querySelector('.btn').appendChild(button);
  </script>
</body>

</html>
posted @ 2018-02-06 20:15  Ajanuw  阅读(200)  评论(0编辑  收藏  举报