日日操夜夜添-日日操影院-日日草夜夜操-日日干干-精品一区二区三区波多野结衣-精品一区二区三区高清免费不卡

公告:魔扣目錄網(wǎng)為廣大站長(zhǎng)提供免費(fèi)收錄網(wǎng)站服務(wù),提交前請(qǐng)做好本站友鏈:【 網(wǎng)站目錄:http://www.ylptlb.cn 】, 免友鏈快審服務(wù)(50元/站),

點(diǎn)擊這里在線咨詢客服
新站提交
  • 網(wǎng)站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會(huì)員:747

當(dāng)今前端編程中,利用語(yǔ)義化的 html 結(jié)合 css 來(lái)完一個(gè)組件并不是一件難事,這也意味著無(wú)論在 ReactVue 中都可以插入,不過(guò)它倆不是今天的主角,接下來(lái)我將用一個(gè)例子來(lái)介紹如何封裝一個(gè)完整的原生 HTML 的 Web Components 組件,讓我們開始吧!

HTML結(jié)構(gòu)

首先我們來(lái)了解下 HTML 中的 <details> 元素,它可以用于創(chuàng)建一個(gè)小部件,其中包含僅在小部件處于“打開”狀態(tài)時(shí)才可見(jiàn)的附加信息,<details>元素內(nèi)可以包含的內(nèi)容沒(méi)有任何限制。

默認(rèn)情況下,元素創(chuàng)建的小部件<details>處于“關(guān)閉”狀態(tài)(open標(biāo)簽可使其打開)。通過(guò)單擊小部件在“打開”和“關(guān)閉”狀態(tài)之間切換,以顯示或隱藏標(biāo)簽中包含的附加信息,內(nèi)部標(biāo)簽 <summary> 元素則可為該部件提供概要。

一個(gè)簡(jiǎn)單的例子如下:

<details>
    <summary> 不能說(shuō)的秘密 </summary>
    藏的這么深,可還是被你發(fā)現(xiàn)了
</details>
details {
    border: 1px solid #aaa;
    border-radius: 4px;
    padding: .5em .5em 0;
}

summary {
    font-weight: bold;
    margin: -.5em -.5em 0;
    padding: .5em;
}

details[open] {
    padding: .5em;
}

details[open] summary {
    border-bottom: 1px solid #aaa;
    margin-bottom: .5em;
}

 

使用語(yǔ)義化 HTML 的優(yōu)點(diǎn):頁(yè)面內(nèi)容結(jié)構(gòu)更清晰,方便開發(fā)者閱讀,更利于瀏覽器的理解與加載,搜索引擎解析與seo優(yōu)化。

添加億點(diǎn)樣式

原生元素默認(rèn)的樣式很簡(jiǎn)陋,因此我們需要為其定制一下樣式,這塊內(nèi)容我們簡(jiǎn)單帶過(guò),只講解關(guān)鍵部分,樣式內(nèi)容有省略,具體可以在文末的碼上掘金中看到呈現(xiàn)效果。

.ContentWarning > summary {
  position: relative;
  list-style: none; /** 去除默認(rèn)樣式 **/
  user-select: none; 
  cursor: pointer;
  /** 為其添加一個(gè)斜線背景 **/
  --stripe-color: rgb(0 0 0 / 0.1);
  background-image: repeating-linear-gradient(45deg,
      transparent,
      transparent 0.5em,
      var(--stripe-color) 0.5em,
      var(--stripe-color) 1em);
}

/** 通過(guò)var變量調(diào)整懸停時(shí)的顏色樣式 **/
.ContentWarning>summary: hover,
.ContentWarning>summary: focus {
  --stripe-color: rgb(150 0 0 / 0.1);
}

 

封裝模板

現(xiàn)在我們來(lái)把它封裝成一個(gè)完整的組件,這需要先將 HTML 編寫在模板 template 當(dāng)中,并設(shè)置一個(gè) id,如下所示:

<template id="warning-card">  
  <details class="ContentWarning">
    <summary>
      <strong>?? 注意:</strong> 以下為隱藏內(nèi)容
    </summary>
    <slot name="desc"> 藏的這么深,可還是被你發(fā)現(xiàn)了 </slot>
  </details>
</template>

熟悉 Vue 的小伙伴應(yīng)該很容易理解上面的代碼,結(jié)構(gòu)很相似,不過(guò)網(wǎng)頁(yè)不會(huì)直接渲染它包裹的內(nèi)容。此外我們還對(duì)此模板設(shè)置了一個(gè)插槽 slot,后面會(huì)講到它的作用。

定義組件

有了上面封裝好的模板,我們就需要在 JS 中定義成可用組件來(lái)讓其能夠被使用,調(diào)用 window 下的 customElements.define 方法,第一個(gè)參數(shù)是傳入組件名稱,我們定義組件名為: warning-card ,第二個(gè)參數(shù)傳入一個(gè)繼承了 HTMLElement 的類,在其構(gòu)造方法當(dāng)中獲取并克隆一個(gè)新的 HTML 節(jié)點(diǎn),它會(huì)通過(guò) AppendChild 渲染到頁(yè)面當(dāng)中。

window.customElements.define('warning-card',
  class extends HTMLElement {
    constructor() {
      super();
      var templateElem = document.getElementById('warning-card');
      var content = templateElem.content.cloneNode(true);
      this.appendChild(content);
    }
  })

接著我們就可以在頁(yè)面中把它當(dāng)作組件那樣使用了:

<warning-card> </warning-card>

插槽與傳參

回頭看看上面我們模板中設(shè)置的插槽 slot,此時(shí)還是沒(méi)有生效的,我們需要稍微改寫一下構(gòu)造函數(shù)中的渲染方式,將 web 組件定義為一個(gè) Shadow DOM,這樣構(gòu)造的是一個(gè)可以將標(biāo)記結(jié)構(gòu)、樣式和行為隱藏起來(lái),并與頁(yè)面上的其他代碼相隔離,保證不同的部分不會(huì)混在一起的獨(dú)立元素,并在最后使用 Node.cloneNode() 方法添加了模板的拷貝到 Shadow 的根結(jié)點(diǎn)上。

window.customElements.define('warning-card',
  class extends HTMLElement {
    constructor() {
      super();
      var template = document.getElementById('warning-card').content;
      this.attachShadow({ mode: 'open' }).appendChild(template.cloneNode(true));
    }
  })

現(xiàn)在我們嘗試使用下組件,往其內(nèi)容添加一個(gè)圖片,指向名為 desc 的 slot 插槽中:

<warning-card>
  <img slot="desc" src="https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/ba825ffee78c4a1b9c0232e5d2f1d048~tplv-k3u1fbpfcp-watermark.image?" />
</warning-card>

這時(shí)你會(huì)發(fā)現(xiàn),圖片插入到 details 元素的隱藏區(qū)域當(dāng)中了,slot 已經(jīng)成功生效,但是樣式卻消失了,這時(shí)因?yàn)榻M件已經(jīng)被完全隔離,我們需要將樣式作用在其內(nèi)部才會(huì)生效。

<template id="warning-card">
  <style>
    <!-- TODO: 組件的樣式 -->
  </style>
  
  <details class="ContentWarning">
    <summary>
      <strong>?? 注意:</strong>
    </summary>
    <slot name="desc">THE DESCRIPTION</slot>
  </details>
</template>

這樣組件就正常了:

 

除了定制模板中的插槽,我們也可以通過(guò) HTML 標(biāo)簽屬性來(lái)實(shí)現(xiàn)一些簡(jiǎn)單的傳參,例如在 summary 標(biāo)簽中顯示一個(gè)標(biāo)題:

<warning-card title="前方高能">
</warning-card>

我們只需要在模板中定義好這個(gè)標(biāo)題的位置:

<template id="warning-card">
  <details class="ContentWarning">
    <summary>
        <!-- TODO: 模板中加入一個(gè)span標(biāo)簽 -->
      <strong>?? 注意:</strong> <span id="title"></span>
    </summary>
  </details>
</template>

最后在構(gòu)造函數(shù)中我們通過(guò) document 的原生方法寫入模板中就可以了:

window.customElements.define('warning-card',
  class extends HTMLElement {
    constructor() {
      super();
      var template = document.getElementById('warning-card').content;
      // TODO: 找到title標(biāo)簽,寫入傳入組件的title屬性值
      template.querySelector('#title').innerText = this.getAttribute('title');
      this.attachShadow({ mode: 'open' }).appendChild(template.cloneNode(true));
    }
  })

結(jié)束

至此,我們通過(guò)一個(gè)簡(jiǎn)單的原生組件學(xué)習(xí)了如何編寫 Web Components,可以在此代碼片段中查看具體源碼:原生Web Components組件 - 碼上掘金原生Web Components組件 - 碼上掘金。

以上就是文章的全部?jī)?nèi)容,希望對(duì)你有所幫助!如果覺(jué)得文章寫的不錯(cuò),可以點(diǎn)贊收藏,也歡迎關(guān)注,我會(huì)持續(xù)更新更多前端有用的知識(shí)與實(shí)用技巧,我是茶無(wú)味de一天,希望與你共同成長(zhǎng)~

分享到:
標(biāo)簽:Web Components
用戶無(wú)頭像

網(wǎng)友整理

注冊(cè)時(shí)間:

網(wǎng)站:5 個(gè)   小程序:0 個(gè)  文章:12 篇

  • 51998

    網(wǎng)站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會(huì)員

趕快注冊(cè)賬號(hào),推廣您的網(wǎng)站吧!
最新入駐小程序

數(shù)獨(dú)大挑戰(zhàn)2018-06-03

數(shù)獨(dú)一種數(shù)學(xué)游戲,玩家需要根據(jù)9

答題星2018-06-03

您可以通過(guò)答題星輕松地創(chuàng)建試卷

全階人生考試2018-06-03

各種考試題,題庫(kù),初中,高中,大學(xué)四六

運(yùn)動(dòng)步數(shù)有氧達(dá)人2018-06-03

記錄運(yùn)動(dòng)步數(shù),積累氧氣值。還可偷

每日養(yǎng)生app2018-06-03

每日養(yǎng)生,天天健康

體育訓(xùn)練成績(jī)?cè)u(píng)定2018-06-03

通用課目體育訓(xùn)練成績(jī)?cè)u(píng)定