自定義標籤的編碼

customElements.define

在MDN官方文檔中,若是你想要使用自定義標籤,可使用customElement類中define方法(IE7如下瀏覽器不支持),
使用:customElements.define('myselfTagName', myselfClass, extendsObj);
參數:css

myselfTagName: 自定義標籤名
myselfClass: 自定義標籤的類對象,(主要功能在這裏實現,通常在自定義標籤綁定變量、事件、指令或者是渲染條件)
extendsObj: 內置並繼承的元素(包裹着自定義標籤的對象,通常不使用,畢竟誰會閒的無聊把基本標籤封裝成自定義標籤而後填充一堆屬性,語義化也說不通啊)

attachShadow

官方文檔對於shadow DOM解釋很模糊,簡單的說就是DOM的'一體雙魂',擁有一樣的函數和方法,可是Shadow DOM比被附加DOM更多的功能,前者具備獨自的做用域,而且與外界DOM分隔。(這個做用就是shadow DOM的核心功能,它可使你編寫的DOM與css與其餘區域互不影響,至關於vue中css樣式<style scoped> </style>的做用);
shadow DOM彌補了customElements缺乏隔離做用域(DOM和css做用域)的缺陷。html

shadom DOM Root的建立方法: this.attachShadow({mode: 'open'});前端

this: shadom DOM對象
mode: 開啓js調用shadow DOM

代碼示範

coding.... 莫道征途路漫漫

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>Pop-up info box — web components</title>
  </head>
  <body>
    <h1>Pop-up info widget - web components</h1>

    <form>
      <div>
        <label for="cvc">Enter your CVC <popup-info img="img/alt.png" data-text="Your card validation code (CVC) is an extra security feature — it is the last 3 or 4 numbers on the back of your card."></label>
        <input type="text" id="cvc">
      </div>
    </form>
  </body>
  <script>
/**
 *
 * @description:將shadow root附加到customelement上,
                 而後經過一系列DOM操做建立custom element的內部陰影DOM結構,
                 再將其附加到 shadow root上,最後再將一些CSS附加到 
                 shadow root的style節點上。
 */
 
class PopUpInfo extends HTMLElement {
  constructor() {
    // 必須使用super初始化customElements類的構造器
    super();

    // 建立shadom Dom Root,該Root 掛載在自定義DOM上,該DOM Root節點是一個真實節點。
    const shadow = this.attachShadow({mode: 'open'});

    // Create spans
    const wrapper = document.createElement('span');
    wrapper.setAttribute('class', 'wrapper');

    let icon = document.createElement('span'),
        info = document.createElement('span'),
        text = this.getAttribute('data-text');
          
    icon.setAttribute('class', 'icon');
    icon.setAttribute('tabindex', 0);
    info.textContent = text;
    info.setAttribute('class', 'info');

    let imgUrl = this.hasAttribute('img') ? this.getAttribute('img'): 'img/default.png',
        img = document.createElement('img');
        
    img.src = imgUrl;
    icon.appendChild(img);

    // 優化樣式
    const style = document.createElement('style');
    console.log(style.isConnected);

    style.textContent = `
      .wrapper {
        position: relative;
      }

      .info {
        font-size: 0.8rem;
        width: 200px;
        display: inline-block;
        border: 1px solid black;
        padding: 10px;
        background: white;
        border-radius: 10px;
        opacity: 0;
        transition: 0.6s all;
        position: absolute;
        bottom: 20px;
        left: 10px;
        z-index: 3;
      }

      img {
        width: 1.2rem;
      }

      .icon:hover + .info, .icon:focus + .info {
        opacity: 1;
      }
    `;

    // 插入shadow dom Root
    shadow.appendChild(style);
    console.log(style.isConnected);
    shadow.appendChild(wrapper);
    wrapper.appendChild(icon);
    wrapper.appendChild(info);
  }
}
// 自定義標籤
customElements.define('popup-info', PopUpInfo);

</script>
</html>

官方示例
MDN CODEvue

思考

自定義標籤的使用減小了咱們頻繁編寫一堆冗餘、深層嵌套的代碼,提升了速率。然而,若是咱們看頁面源碼會發現customElements.define不會消除自定義標籤,自定義標籤若是綁定了大量的數據、事件、敏感信息,頁面上又徹底顯示出來,這就增長前端頁面的不安全性。如何保證開發者即便用自定義標籤又不會編譯自定義標籤從而致使DOM的過分掛載和數據的泄漏(不建議remove自定義標籤,頻繁操做DOM太消耗內存了),值得思考...git

相關文章
相關標籤/搜索