Web Component--01. 簡介


Web Components 是什么?

Web Components是W3C定義的新標准,它給了前端開發者擴展瀏覽器標簽的能力,可以自由的定制組件,更好的進行模塊化開發,徹底解放了前端開發者的生產力。

Web Components 架構

Web Components在 W3C 規范中的發展有幾個模塊:

  • 模板元素
  • Html Import
  • Shadow DOM
  • 自定義元素
  • 裝飾器

目前前四個模塊足以支撐 Web Component,裝飾器還沒有一個完整的規范。

template 模板元素

創建一個template的 html 標簽,通過 javascript 獲取節點的模板內容

<template id="test">
test template
</template>
<h1 id="message"></h1>
<script type="text/javascript">
    var template = document.getElementById("test");
    console.log(template.content);
</script>

模板默認不顯示,需要激活模板,通過以下兩種方法來激活節點

  • 克隆節點

    var templateContent  = template.content;
    var activeNode = templateContent.cloneNode(true);
    document.body.appendChild(activeNode);
    
  • 導入節點

    var templateContent  = template.content;
    var activeNode = document.importNode(templateContent,true);
    document.body.appendChild(activeNode);
    

Html Import

Html Import 可以將外部的 HTML 文檔嵌入到當前文檔中,提供很好的資源共享。
帶有import屬性的link 支持兩個事件

  • onload:文件成功引入頁面會觸發

  • onerror: 文件加載失敗會觸發

    <script type="text/javascript"> function importTest(message){ console.log(message); } </script>

     

Shadow DOM

在 Web Component 規范出來之前,關於 HTML、CSS、Javascript 構建 Web 應用程序的程序的爭論一直不斷。主要質疑有幾種:

  • 樣式覆蓋:文檔的樣式會影響Web Component
  • 腳本替換:文檔的Javascript會覆蓋Web Component的部分代碼
  • 重復的 ID:文檔出現重復 ID 會導致解析異常

Shadow DOM的引入就是為了解決封裝機制作用域的問題。
瀏覽器通常情況下是看不到Shadow DOM節點的,Google 開發工具可以幫我審查這些元素,需要做如下設定:

創建Shadow DOM : 通過 createShadowRoot 函數對一個 DOM 元素(宿主元素)創建一個 Shadow DOM 子樹

<div id="box"></div><!--容器-->
<template id="test">
<style>
:host h1{color:red};
</style>
<h1>Test</h1>
</template>
<script type="text/javascript">
    var box = document.getElementById("box");
    var shadowRoot = box.createShadowRoot();
    var template = document.getElementById("test");
    var templateContent  = template.content;
    var activeNode = document.importNode(templateContent,true);
    shadowRoot.appendChild(activeNode);
</script>

自定義元素

開發一個自定義元素需要五個步驟:

  • 創建對象:

    var objectProto = Object.create(HTMLElement.prototype);
    
  • 定義對象屬性:

    //定義單個屬性
    Object.defineProperty(objectProto,'title',{
        writable : true,
    })
    
    //定義單個多個
    Object.defineProperties(objectProto,{
        height: {writable : true},
        width: {writable : true}
    })
    
  • 定義生命周期方法:

    //成功創建對象
    objectProto.createdCallback = function(){
        console.log('created');
    }
    //對象插入DOM中
    objectProto.attachedCallback = function(){
        console.log('attached');
    }
    
  • 注冊新元素

    document.registerElement('test',{
            prototype : objectProto
    });
    

輸入24px 的 HelloWorld:

<my-name title="HelloWorld" fontsize="2"></my-name>
<script type="text/javascript">
    var objectProto = Object.create(HTMLElement.prototype);
    Object.defineProperties(objectProto,{
        title: {writable : true},
        fontsize: {writable : true}
    })
    objectProto.createdCallback = function(){
        this.innerText = this.attributes.title.value;
        this.style.fontSize = this.attributes.fontsize.value * 12 + 'px';
    }
    document.registerElement('my-name',{
        prototype : objectProto
    });
</script>

時鍾應用

  • test.html :通過import方式加載Clock Component
  • clock-elemect.html:負責倒計時的實現

test.html

<link rel="import" href="clock-element.html"/>
<digital-clock></digital-clock>

clock-elemect.html

<template id="clockTemplete">
    <style>
    :host::shadow .clock{
        display: inline-flex;
        justify-content: space-around;
        background:white;
        font-size: 8rem;
        box-shadow: 2px 2px 4px -1px grey;
        border: 1px solid green;
        font-family: sans-serif;
        width: 100%;
    }
    :host::shadow .clock .hour,
    :host::shadow .clock .minute,
    :host::shadow .clock .second{
        color: orange;
        padding: 1.5rem;
        text-shadow: 0px 2px black;
    }
    </style>
    <div class="clock">
        <div class="hour">HH:</div>
        <div class="minute">MM:</div>
        <div class="second">SS</div>
    </div>
</template>
<script type="text/javascript">
(function(){
    var selfDoucment = document.currentScript.ownerDocument;
    var objectProto = Object.create(HTMLElement.prototype);
    objectProto.createdCallback = function(){
        var shadow = this.createShadowRoot();
        var templateContent = selfDoucment.querySelector('#clockTemplete').content;
        var templateNode = selfDoucment.importNode(templateContent,true);
        shadow.appendChild(templateNode);
        var hourElement = shadow.querySelector('.hour');
        var minuteElement = shadow.querySelector('.minute');
        var secondElement = shadow.querySelector('.second');
        window.setInterval(function(){
            var date = new Date();
            hourElement.innerText = date.getHours()+':';
            minuteElement.innerText = date.getMinutes()+':';
            secondElement.innerText = date.getSeconds();
        },1000);
    };
    document.registerElement('digital-clock',{
        prototype : objectProto
    });
})();
</script>





 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM