Custom Element Practice

Custom Element Practice Custom Element (自定義元素), Shadow DOM (影子 DOM), HTML Template (HTML 模板)

by hugogo7646

HTML

<div id="aDiv">Normal DOM</div>
<!-- 使用設定好了的 Custom Element -->
<my-custom-dom>
  <div slot="slot1">Slot 1</div>
  <div slot="slot2">Slot 2</div>
  <div>No Slot</div>
</my-custom-dom>

<!-- 設定等下要給 Shadom DOM 用的 template -->
<template id="my-template">
  <!-- Shadom DOM  -->
  <style>
    div {
      background-color: #00FF00;
    }
  </style>
  <!-- 雖然 id="aDiv" 上面已經有 DOM 用過了,
  但因為是在 Shadom DOM 裡面,所以互相獨立不衝突 -->
  <div id="aDiv">Custom DOM</div>
  <!-- <slot> 雖然會內嵌在 Custom DOM 中顯示,但是本體是處在 Shadom DOM 之外 
  ,所以不會受到 Shadow DOM 的 CSS 影響,
  ,而是會受到 Shadom DOM 外部的 CSS 影響-->
  <div><slot name="slot1"></slot></div> <!-- <div slot="slot1"> 會顯示在這裡 -->
  <slot name="slot2"></slot> <!-- <div slot="slot"> 會顯示在這裡 -->
  <slot></slot> <!-- 沒設定 slot 屬性的 <div> 會顯示在這裡 -->
</template>

CSS

/* 不會作用到 Shadom DOM 裡面 */ 
div {
  color: #0000FF;
  background-color: #FF0000;
}

JavaScript

class MyCustomDom extends HTMLElement {
  constructor() {
    super();
  }
  connectedCallback() {
    //在這裡 shadowRoot == this.shadowRoot
    var shadowRoot = this.attachShadow({
      mode: "open"
    });
    shadowRoot.appendChild(document.getElementById("my-template").content);
    //也可以不用 HTML 上的 <template>,
    //改用 Javascript 自己建立 <template>,範例如下: 
    /*
    var template = document.createElement('template');
    template.innerHTML = `
    	<style> ... some style </style>
    	<div id='aDiv'>Custom DOM</div> ... some DOM, some <slot>
      `;
    shadowRoot.appendChild(template.content);
    */    
    //我們在這也可以把 shadowRoot 當做像是 shadow DOM 裡面的 document來用,
    //add 一些 eventListener、修改一下 DOM Element 等
    shadowRoot.getElementById("aDiv").addEventListener("click", function() {
    	console.log("Clicked!!");
    });
  }
}
customElements.define("my-custom-dom", MyCustomDom);