实现checkbox组件化(Component)
之前我写了一篇自定义checkbox的文章,通过css3实现自定义的checkbox,并没有使用当今流行的Reactjs, 或者Vuejs之类的进行组件化。但是很显然,这样封装的checkbox组件复用的时候非常麻烦。如果在新项目中使用的话,可能需要同时拷贝css和html文件进行整合。从html语义角度上讲,代码的易读性也不是很强,显然这样的组件显然不利于维护。
其实Web Component是前端界一直非常热衷的一个领域,因为原生的HTML在维护复杂网页应用时,实在是太差了。所以才出现了诸如Google的Ploymer
、Facebook的Reactjs
等等。而且很多MVVM
的框架也自带组件化的方案,例如Angularjs
的指令,但貌似ng
的这个用起来太复杂。用第三方组件化的框架去实现的话,你需要依赖框架本身很多东西,很多时候我们只是简单的几个组件,不是很大,也不是很多,所以为了保证组件的轻量,简单
,其实这个时候我们并不想采用第三方的框架。接下来我会介绍使用Shadow DOM和registerElement
的方式去实现组件化。
先看看实现后的调用方式:
<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
组件。效果如下:
好了看了效果,我们来看看具体怎么实现的吧。在线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
时使用。 同时我们在原型对象上定义了checked
和value
对象,方便调用组件时使用。通过get
,set
方法我们与其相对应的checked
和value
属性(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获取元素,可通过checked
和value
对象直接访问。
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
实现checkbox组件化(Component)的更多相关文章
- 【vue-03】组件化开发 component
vue组件化思想 组件化是vue的一个重要思想 它提供了一种抽象,让我们可以开发出一个个独立可复用的小组件来构建我们的应用. 任何的应用都会被抽象成一颗组件树. 注册组件 组件的使用分成三个步骤:创建 ...
- 【转】组件化的Web王国
本文由 埃姆杰 翻译.未经许可,禁止转载!英文出处:Future Insights. 内容提要 使用许多独立组件构建应用程序的想法并不新鲜.Web Component的出现,是重新回顾基于组件的应用程 ...
- 谈谈我对前端组件化中“组件”的理解,顺带写个Vue与React的demo
前言 前端已经过了单兵作战的时代了,现在一个稍微复杂一点的项目都需要几个人协同开发,一个战略级别的APP的话分工会更细,比如携程: 携程app = 机票频道 + 酒店频道 + 旅游频道 + ..... ...
- 漫谈Nuclear Web组件化入门篇
目前来看,团队内部前端项目已全面实施组件化开发.组件化的好处太多,如:按需加载.可复用.易维护.可扩展.少挖坑.不改组件代码直接切成服务器端渲染(如Nuclear组件化可以做到,大家叫同构)... 怎 ...
- React Native 之 组件化开发
前言 学习本系列内容需要具备一定 HTML 开发基础,没有基础的朋友可以先转至 HTML快速入门(一) 学习 本人接触 React Native 时间并不是特别长,所以对其中的内容和性质了解可能会有所 ...
- Vue.js:轻量高效的前端组件化方案
转发一篇尤老师对vue.js的介绍,了解vue.js的来龙去脉.不过现在已经是2.0了,也有添加一些新的东西,当然有些东西也改了. Vue.js:轻量高效的前端组件化方案 Vue.js 是我在2014 ...
- 移动web端的react.js组件化方案
背景: 随着互联网世界的兴起,web前端开发的方式越来越多,出现了很多种场景开发的前端架构体系,也对前端的要求日益增高,早已经不是靠一个JQuery.js来做前端页面的时代了,而今移动端变化最大,近 ...
- 【腾讯Bugly干货分享】打造“微信小程序”组件化开发框架
本文来自于腾讯Bugly公众号(weixinBugly),未经作者同意,请勿转载,原文地址:http://mp.weixin.qq.com/s/2nQzsuqq7Avgs8wsRizUhw 作者:Gc ...
- vue.js组件化开发实践
前言 公司目前制作一个H5活动,特别是有一定统一结构的活动,都要码一个重复的轮子.后来接到一个基于模板的活动设计系统的需求,便有了下面的内容.借油开车. 组件化 需求一到,接就是怎么实现,技术选型自然 ...
随机推荐
- angularjs flask跨域问题 XMLHttpRequest cannot load. No 'Access-Control-Allow-Origin'
场景,我要来我的server(A)上用api来访问另一个server(B)的问题,如果直接在A上调用B的api,那么就会出现XMLHttpRequest cannot load. No 'Access ...
- Effective Java 29 Consider typesafe heterogeneous containers
When a class literal is passed among methods to communicate both compile-time and runtime type infor ...
- session失效后跳转到登陆页面
一.编写Filter拦截器类 package com.pv.utils; import java.io.IOException; import java.io.PrintWriter; import ...
- 烂泥:KVM快照的创建与恢复
本文由秀依林枫提供友情赞助,首发于烂泥行天下. 因为要做有关KVM虚拟机的实验,所以需要虚拟机生成快照.查询相关资料,说KVM可以使用两种方法生成虚拟机的快照. 方法一.使用qemu-img snap ...
- 计算几何--判断两条线段相交--poj 2653
Pick-up sticks Time Limit: 3000MS Memory Limit: 65536K Total Submissions: 8862 Accepted: 3262 De ...
- Python 元组知识点
1.元组是一个有序的集合,2.元组和列表一样可以使用索引.切片来取值.3.创建元组后不能在原地进行修改替换等操作.4.元组支持嵌套,可以包含列表.字典和不同元组.5.元组支持一般序列的操作,例如:+. ...
- 认识与学习 BASH
2015-08-03摘自鸟哥 什么是变量? 那么,什么是『变量』呢?简单的说,就是让某一个特定字符串代表不固定的内容就是了.举个大家在国中都会学到的数学例子, 那就是:『 y = ax + b 』这东 ...
- iscroll.js的使用
入门 Scroll是一个类,每个需要使用滚动功能的区域均要进行初始化.每个页面上的iScroll实例数目在设备的CPU和内存能承受的范围内是没有限制的. 尽可能保持DOM结构的简洁.iScroll使用 ...
- 深入.NET框架 项目《魔兽登录系统》
创建魔兽系统相关窗体: 登录窗体(frmLogin) 注册窗体(frmRegister) 主窗体 (frmMain) 实现魔兽登录系统: 登录的界面如下 实现思路: 1.创建一个对象数组,长度为1 ...
- as3 Point
首先我们看看Point类的属性:x:Number——该点的水平坐标y:Number——该点的垂直坐标length:Number——从(0,0)到此点的线段长度(只读属性)从length属性我们可以看到 ...