實現checkbox組件化(Component)


之前我寫了一篇自定義checkbox的文章,通過css3實現自定義的checkbox,並沒有使用當今流行的Reactjs, 或者Vuejs之類的進行組件化。但是很顯然,這樣封裝的checkbox組件復用的時候非常麻煩。如果在新項目中使用的話,可能需要同時拷貝css和html文件進行整合。從html語義角度上講,代碼的易讀性也不是很強,顯然這樣的組件顯然不利於維護。

其實Web Component是前端界一直非常熱衷的一個領域,因為原生的HTML在維護復雜網頁應用時,實在是太差了。所以才出現了諸如Google的Ploymer、Facebook的Reactjs等等。而且很多MVVM的框架也自帶組件化的方案,例如Angularjs的指令,但貌似ng的這個用起來太復雜。用第三方組件化的框架去實現的話,你需要依賴框架本身很多東西,很多時候我們只是簡單的幾個組件,不是很大,也不是很多,所以為了保證組件的輕量,簡單,其實這個時候我們並不想采用第三方的框架。接下來我會介紹使用Shadow DOMregisterElement的方式去實現組件化。

先看看實現后的調用方式:

<div class="line"> <label>checkbox1 </label> <check-box class="mycheck" checked="true" id="ComCheckbox"></check-box> </div> <div class="line"> <label>checkbox2 </label> <check-box class="mycheck" checked="false" id="ComCheckbox1" value="2"></check-box> </div>

看起來是不是很簡潔,調用自定義的checkbox組件不需要那么多擾亂閱讀的元素,只需要一個明確的check-box標簽,既可以表示checkbox組件。效果如下:

 

Checkbox-Demo

 

好了看了效果,我們來看看具體怎么實現的吧。在線demo查看

組件的組成

通常情況下,我們一個組件一般是由html模板,css樣式,js腳本邏輯三部分組成的。他們的作用我就不多廢話了。至於當前組件的css樣式自定義方法請看我上一篇文章CSS3實現自定義checkbox,這里我就不重復這部分了。

  • 在項目工作區新建一個component-checkbox.html文件, 這個文件會被當做整個組件,在我們需要引用的頁面中通過link標記動態的引入。 component-checkbox.html文件即包含了HTML模板,CSS樣式,JS三個部分,他們在組件文件中的分布如下:
<template> <style>// 放CSS樣式定義</style> // 放HTML標記 </template> <script type="text/javascript"> // JS腳本邏輯 </script>

具體HTML/CSS定義

    <template id="CheckBox"> <style> .slide-checkbox { position: relative; width: 120px; height: 40px; line-height: 40px; border-radius: 30px; background: #4fbe79; } .slide-checkbox input[type=checkbox] { visibility: hidden; } .slide-checkbox label { position: absolute; height: 30px; width: 30px; left: 5px; top: 5px; background: #FFFFFF; border-radius: 50% 50%; -webkit-transition: all .4s ease; -moz-transition: all .4s ease; -o-transition: all .4s ease; -ms-transition: all .4s ease; transition: all .4s ease; } .slide-checkbox input[type=checkbox]:checked + label { left: 85px; } </style> <div class="slide-checkbox"> <input type="checkbox" name="checkbox" id="SlideCheck" /> <label for="SlideCheck"></label> </div> </template>

JS的實現

這種組件實現發方法,重點地方就在JS腳本這個部分,所以請看下面的詳細描述。

1. Shadow DOM說明

Shadow DOM提供了一種獨立封裝`html', 'css', 'js'到組件文件的一種方法,這樣Shadow DOM內部的樣式文件及js等等都與引用頁面處於隔離狀態,互相獨立,所以不必擔心他們之間會不會出現樣式,js相互亂引用的情況出現。當然調用頁面與Shadow DOM的通信則需要通過js來完成。

2. registerElement說明

可以在瀏覽器中實現自定義element, 當然會有人想到說'document.createElement()'方法也可以創建不同的元素,但是很顯然registerElement更強大些,具體就不展開了。

3. 詳細JS代碼

// Whether registerElement is supported function isCustomElementSupported() { return 'registerElement' in document; } (function() { "use strict"; if (isCustomElementSupported()) { var objectPrototype = Object.create(HTMLElement.prototype); var selfDoc = document.currentScript.ownerDocument; Object.defineProperty(objectPrototype, 'value', { get: function() { return this.getAttribute("value") || null; }, set: function(value) { this.setAttribute("value", value); } }); Object.defineProperty(objectPrototype, 'checked', { get: function() { return this.getAttribute("checked") || false; }, set: function(isChecked) { shadowChecked(this, isChecked); this.setAttribute("checked", isChecked); } }); objectPrototype.createdCallback = function() { var self = this; var rootElement = self.createShadowRoot(); var templateContent = selfDoc.querySelector("#CheckBox").content; var nodes = document.importNode(templateContent, true); // Add template content to shadowRoot element rootElement.appendChild(nodes); var checkbox = rootElement.querySelector("#SlideCheck"); // init checked value if (self.checked == "true") { checkbox.checked = true; } // Add change event to checkbox checkbox.addEventListener('change', function() { self.checked = this.checked; }); }; var checkbox = document.registerElement('check-box', { prototype: objectPrototype }); } // update shadow root function shadowChecked(self, isChecked) { var shadowCheck = self.shadowRoot.querySelector("#SlideCheck"); shadowCheck.checked = isChecked; } })();

4. 代碼描述

該代碼片段先定義了一個registerElement支持情況的檢測方法。在匿名函數中先經過支持檢測后,通過Object對象創建了有一個HTMLElement的原型對象,用於注冊checkbox繼承HTMLElement時使用。 同時我們在原型對象上定義了checkedvalue對象,方便調用組件時使用。通過get,set方法我們與其相對應的checkedvalue屬性(attribute)產生聯系,便於數據通信。

createdCallback方法在組件被創建后執行。首先將獲取到template里的內容添加到rootElement中, 添加完后我們便可以進行一些初始化組件的操作。例如初始化checked的狀態值, 模板內置的checkbox添加change的事件綁定,便於實時更新組件當前的checked值。

組件的使用

1. 引用組件

首先我們需要在要使用該組件的HTMl頁面中引入組件文件。
注:由於該文件是用過HTTP讀取過來的,所以靜態項目可能無法獲取組件文件,需要把這些文件放到服務器目錄下去訪問。 引入方式:

<link rel="import" href="com-checkbox.html">

2. 使用

在需要使用該組件的位置放入組件標簽即可:

<check-box class="mycheck" checked="true" value="1" id="ComCheckbox"></check-box>

注:class為樣式類名,checked為初始化狀態, value為checkbox值。

當然你也可以多次引用組件,例如同時使用4個,實際狀況中可能會更多:

<div class="line"> <label>checkbox1 </label> <check-box class="mycheck" checked="true" value="1" id="ComCheckbox"></check-box> </div> <div class="line"> <label>checkbox2 </label> <check-box class="mycheck" checked="false" value="2" id="ComCheckbox1" value="2"></check-box> </div> <div class="line"> <label>checkbox3 </label> <check-box class="mycheck" value="3" checked=false id="ComCheckbox2" value="3"></check-box> </div> <div class="line"> <label>checkbox4 </label> <check-box class="mycheck" value="4" checked="true" id="ComCheckbox3" value="4"></check-box> </div>

3. 獲取check-box的狀態和值

var checkbox = document.querySelector("#ComCheckbox"); console.log(checkbox.checked); // output: true console.log(checkbox.value); // output: 1

根據ID獲取元素,可通過checkedvalue對象直接訪問。

4. 實現checkbox全選和取消

var checkboxs = document.querySelectorAll("check-box"); function selectAll() { for (i = 0; i < checkboxs.length; i++) { checkboxs[i].checked = true; } } function cancleSelectAll() { for (i = 0; i < checkboxs.length; i++) { checkboxs[i].checked = false; } }

獲取所以的checkbox列表, 然后遍歷改變checked的狀態。其他復雜操作或者情況可以再組件定義時進行擴展。

總結

以上便是整個組件定義的具體方法。當然今天我們自定義的是checkbox組件,我們當然可以通過該方法去實現其他的組件,例如radio,select等等。

原文地址:http://imziv.com/blog/article/read.htm?id=72


免責聲明!

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



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