热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

ZLComboBox自定义控件开发详解

【引言】距离上一回写博客已经有一些时日了,之前的爱莲iLinkIT系列主要是讲解了如何用NodeJS来实现一个简单的“文件传送”软件,属于JavaScr

【引言】距离上一回写博客已经有一些时日了,之前的爱莲iLinkIT系列主要是讲解了如何用NodeJS来实现一个简单的“文件传送”软件,属于Javascript中在服务器端的应用。

今天,我们就回归到Javascript的主战场 ---- 前端设计,一起来聊聊如何开发一个“自定义”的Web控件(基于jQuery),属于基础级别,高手请轻拍,还望不吝赐教,先谢过。

 

我们先假设这样一个场景,BOSS下达了命令,要求开发一款“幼儿早教”的应用,方便小朋友进行选择操作,而你则负责设计一个“下拉框”的Web控件,方便团队中其他弟兄使用,设计师的MM已经把效果图设计好了,如下:

总的来说,这是一个类似“下拉框”的Web控件:

a. 用户单击控件之后,显示下拉列表。

b. 选中下拉列表中的某项(例如:桃子),会将选中项的图片显示出来。

 

接下来,就让我们一步一步来实现这样的功能,我们先对整个讲解过程做一个整体的规划,以便我们心中有谱:

1. 实现控件的外观部分:包括HTML代码的组织,CSS样式设计。

2. 实现控件的基本框架:用Javascript实现控件的交互设计。

3. 优化控件的可扩展性:让控件可以接受Javascript回调函数。

4. 优化控件的可用性:可以动态传入选项的数据,达到自定义选项列表的目的。

最后,我们来做一个简单的回顾和总结。单击此处下载演示包,解压缩后打开index.html页面体验。

实现控件的外观部分

我们先来分析一下整个控件的几个组成部分,然后组织我们的HTML代码,为了后面设计CSS样式表的方便,在组织HTML代码时,就应该遵照相关规范(例如:公司的样式表命名规范),完成class的名称设计。

控件的组成

控件的最外层是一个大的容器,包含控件的各个组成部分,其中的组件包括:
1. 结果显示框

可以将选中的选项显示在结果显示框中。

2. 下拉框按钮

控制下拉框的显示与隐藏,单击按钮,显示下拉列表,再次单击时,隐藏下拉框,不同的状态下,箭头的方向不一样。

3. 下拉框

下拉框中包含多个可供用户选择的“项”。

4. 下拉框中的项

选项包含图片和文字两个部分,当前被选中的选项,应该呈现不同的外观。 

HTML代码

根据前面的组成分析,我们可以实现如下的HTML代码(index.html):

1 <div class&#61;"zl_combobox">
2 <div class&#61;"cb_input"><img src&#61;"images/f_apple.png" /><span>苹果span>div>
3 <span class&#61;"cb_btn">span>
4 <ul class&#61;"item_list">
5 <li><img src&#61;"images/f_apple.png" /><span>苹果span>li>
6 <li><img src&#61;"images/f_lemon.png" /><span>柠檬span>li>
7 <li><img src&#61;"images/f_peach.png" /><span>桃子span>li>
8 <li><img src&#61;"images/f_watermelon.png" /><span>西瓜span>li>
9 ul>
10 div>

其中&#xff1a;

  • zl_combobox&#xff1a;代表整个Web控件。
  • cb_input&#xff1a;结果显示框。
  • cb_btn: 下拉框按钮。
  • item_list&#xff1a;下拉框。下拉框中的“项”用
  • 元素来表示。

CSS样式表设计

接下来我们要根据控件最终的效果图和前面设计的HTML代码&#xff0c;来完成样式表的设计。在设计样式表时&#xff0c;一般分为两个部分&#xff1a;

  • 基础外观&#xff1a;包括各个子部件的部件、关联关系、呈现外观等。
  • 状态样式&#xff1a;要考虑到控件在交互过程中的状态变化&#xff0c;通过‘开关’来实现不同状态下的外观&#xff0c;方便后续的Javascript的控制。

基础外观的相关CSS代码(zlbox.css)如下&#xff1a;

1 .zl_combobox{
2 position:relative;
3 width:180px;
4 font-size:1.5em;
5 margin-left:5px;
6 color:#323232;
7 }
8 .zl_combobox .cb_input{
9 width:170px;
10 height:60px;
11 padding:0px 5px;
12 line-height:60px;
13 border:1px #A9A9A9 solid;
14 background-color:#F2F2F2;
15 cursor:pointer;
16 }
17 .zl_combobox .cb_input:after,
18 .zl_combobox .item_list li:after{
19 content:&#39;&#39;;
20 clear:both;
21 display:table;
22 }
23 .zl_combobox .cb_input span,
24 .zl_combobox .item_list li span{
25 display:block;
26 padding-left:10px;
27 height:60px;
28 line-height:60px;
29 }
30 .zl_combobox .cb_input img,
31 .zl_combobox .item_list li img{
32 display:block;
33 width:50px;
34 height:50px;
35 }
36 .zl_combobox .cb_input>img,
37 .zl_combobox .cb_input>span,
38 .zl_combobox .item_list li>img,
39 .zl_combobox .item_list li>span
40 {
41 float:left;
42 }
43 .zl_combobox .cb_btn{
44 position:absolute;
45 right:0px;
46 top:1px;
47 width:60px;
48 height:60px;
49 background:url(&#39;img/cb_btn_down.png&#39;) no-repeat center center;
50 cursor:pointer;
51 }
52 .zl_combobox .item_list{
53 display:none;
54 position:absolute;
55 right:0px;
56 top:62px;
57 width:180px;
58 line-height:60px;
59 background-color:#FEFEFE;
60 z-index:999;
61 }
62 .zl_combobox .item_list li{
63 padding-left:10px;
64 border-bottom:2px #CCCCCC dotted;
65 cursor:pointer;
66 }

因为本文重点在于介绍Web控件的设计过程&#xff0c;关于CSS设计的细节&#xff0c;就不展开细讲&#xff0c;如有疑问&#xff0c;咱们在评论中交流讨论。

那么&#xff0c;整个控件在交互过程中&#xff0c;会有哪些状态需要考虑呢&#xff1f;

1. 默认的状态&#xff1a;不显示下拉框&#xff0c;仅仅显示“结果显示框”和“下拉框按钮”。

2. 下拉框展开状态&#xff1a;显示下拉框&#xff0c;并且下拉框按钮的箭头变为向上。

3. 选项的鼠标悬停状态&#xff1a;当鼠标悬停到选项时&#xff0c;改变不同的样式。

(当然&#xff0c;如果你确定你的控件只是在手机/Pad上使用&#xff0c;可以不考虑鼠标悬停)。

4. 被选中的选项的状态&#xff1a;这个可以根据需要设计。

状态相关的样式的CSS代码(zlbox.css)如下&#xff1a;

1 .zl_combobox.selected .item_list{
2 display:block;
3 }
4 .zl_combobox.selected .cb_btn{
5 background:url(&#39;img/cb_btn_up.png&#39;) no-repeat center center;
6 }
7 .zl_combobox .item_list li:hover{
8 color:#5281F8;
9 }

注意到&#xff0c;我们通过判断控件主体.zl_combobox是否有selected的class来控制下拉框的显示状态。

至此&#xff0c;控件的外观部分设计已经完成&#xff0c;我们可以看到&#xff0c;Web控件的外观设计有以下几个特点&#xff1a;

a. 布局属性&#xff1a;Web控件可能在各种场合中使用&#xff0c;所以&#xff0c;我们一般不对控件主体的布局属性进行设置(举例中我们仅仅设置了margin-left:5px&#xff0c;约定控件在使用过程中&#xff0c;距离它前面的控件为5px)。

b. 基础属性&#xff1a;像字体大小、字体颜色这样基础属性&#xff0c;在控件主体中尽量设置一下&#xff0c;确保控件的风格可以得到保证。比如&#xff1a;常规情况下&#xff0c;背景色是白色的&#xff0c;而字体的颜色是黑色&#xff0c;这时候&#xff0c;黑色的字体在白色背景的下拉框中可以显示出来。假设你没有设置控件主体的字体颜色&#xff0c;而在某个使用环境中&#xff0c;背景变成了黑色&#xff0c;字体颜色设置为白色&#xff0c;由于样式具有继承的特性&#xff0c;这时候就会变成在白色下拉框中的字体颜色是白色的。所以&#xff0c;在控件主体中设置基础属性&#xff0c;可以有效避免外部环境的“入侵”&#xff0c;让控件的风格自成一体。

实现控件的基本框架

工程文件组织

尽管前面我们已经讲解了控件的外观设计&#xff0c;也写了相关的HTML代码和CSS代码&#xff0c;但其实有一个本来应该先做的事情没有完成&#xff0c;就是工程文件组织&#xff0c;如下所示&#xff1a;

控件主文件夹的说明如下&#xff1a;

  • css&#xff1a;保存项目用到的CSS相关的文件。
  • images&#xff1a;保存需要在项目中直接引用的图片资源。
  • js&#xff1a;保存项目用到的Javascript相关的文件。
  • index.html&#xff1a;HTML主体文件。

CSS文件夹下的内容&#xff1a;

  • img&#xff1a;保存在css样式表中要引用的背景图片资源。
  • index.css&#xff1a;与工程相关的样式表&#xff0c;比如&#xff1a;页面布局等。
  • reset.css&#xff1a;一个重置样式表&#xff0c;将HTML中元素的标准特性重置。
  • zlbox.css&#xff1a;与控件相关的样式表。

JS文件夹下的内容&#xff1a;

  • jquery.zlbox.js&#xff1a;与控件相关的Javascript文件&#xff0c;因为我们用到了jQuery库&#xff0c;所以以jquery为前缀。
  • jquery.1.7.1.js&#xff1a;jQuery库文件。

本来应该还有一个index.js&#xff0c;用于保存工程相关的js代码&#xff0c;考虑到我们的演示demo的内容比较简单&#xff0c;工程相关的js代码调用就直接放到index.html文件中。

关于工程文件的组织和命名&#xff0c;各个公司应该有各自的规范标准&#xff0c;实际使用过程中&#xff0c;请遵照公司的规范。本文的论述将按以上的组织来进行。

Javascript代码设计

总算到了我们Web控件设计的核心环节&#xff0c;我们的控件是基于jQuery库来设计的。jQuery插件的设计方法有很多种&#xff0c;我们依据我们的业务特点&#xff0c;选用了下面的基本框架模式&#xff0c;核心代码如下&#xff1a;

1 $.fn.czl_combobox &#61; function( options )
2 {
3 this.each( function()
4 {
5 var instance &#61; $.data( this , &#39;czl_combobox&#39; );
6 if( !instance )
7 {
8 $.data( this, &#39;czl_combobox&#39; , new $.ZLComboBox( options , this ) );
9 }
10
11 });//end of each
12
13 return this;
14 };
15 $.ZLComboBox &#61; function( options , element )
16 {
17 this.$el&#61; $( element );
18 this._init( options );
19 };
20 $.ZLComboBox.defaults &#61; {
21
22 };
23 $.ZLComboBox.prototype &#61; {
24 _init : function( options ) {
25 //初始化函数
26 },
27 _loadEvents:function( ){
28 //控件相关的事件注册
29 }
30 };

我们先来看一下调用这个Web控件的代码&#xff0c;然后我们对照起来分析&#xff1a;

$(&#39;.zl_combobox&#39;).czl_combobox( {} );

让前端的HTML元素和后端的Javascript代码关联起来&#xff0c;czl_combobox 这个函数是关键&#xff0c;所以&#xff0c;我们就从$.fn.czl_combobox这个函数入手&#xff0c;来看看它到底是如何关联的&#xff0c;先看代码&#xff1a;

1 $.fn.czl_combobox &#61; function( options )
2 {
3 this.each( function()
4 {
5 var instance &#61; $.data( this , &#39;czl_combobox&#39; );
6 if( !instance )
7 {
8 $.data( this, &#39;czl_combobox&#39; , new $.ZLComboBox( options , this ) );
9 }
10
11 });//end of each
12
13 return this;
14 };

1. czl_combobox是$.fn的成员&#xff0c;意味着凡是jQuery对象都可以调用它。

2. 通过$.data()获取jQuery对象(对应一个HTML元素)的名称为czl_combobox的数据对象。

   如果不存在&#xff0c;那么&#xff0c;就通过$.data()新建一个ZLComboBox 的对象。

   如果已存在&#xff0c;那么&#xff0c;就不重复创建对象。

3. 创建对象时&#xff0c;把当前jQuery对象和参数options传入。

经过分析&#xff0c;我们发现$.fn.czl_combobox也仅仅是桥梁&#xff0c;还不是控件的核心&#xff0c;真正的核心是ZLComboBox对象&#xff0c;这个对象可以通过对应的HTML元素访问到。

现在&#xff0c;我们依据控件的业务特征&#xff0c;先来预估一下ZLComboBox对象能做什么&#xff1a;

1. 既然将HTML元素对应的DOM对象作为参数传给ZLComboBox对象&#xff0c;那么&#xff0c;ZLComboBox对象就能对相关的HTML元素以及它的子元素进行操作。

2. 同时将参数options传递给ZLComboBox对象&#xff0c;意味着&#xff0c;可以根据业务需要对ZLComboBox对象进行一些”定制”操作&#xff0c;包括&#xff1a;属性和行为。

 

下面我们再来看一下ZLComboBox的核心代码&#xff1a;

1. 在它的构造函数中&#xff0c;将传入的HTML DOM对象保存到自己的一个属性成员中&#xff0c;并且将参数options传递给自己的一个初始化方法(_init())。

2. 在它的原型中&#xff0c;定义了_init() 和 _loadEvents()两个方法。

 

我们的目的是要让控件能够响应’单击’事件&#xff0c;并且对控件的各个子部件进行状态的改变&#xff0c;所以我们可以这样操作&#xff1a;

1. 在_init中&#xff0c;通过控件主体的 DOM对象&#xff0c;获得它的各个子部件的jQuery对象。

2. 在_loadEvents中&#xff0c;对子部件的jQuery对象绑定响应事件。

3. 增加一个属性selected_index&#xff0c;记录当前选中的项的序号。

4. 定义一个方法_show_itemlist&#xff0c;用来操作下拉框的显示和隐藏。

完整的JS代码(zlbox.js)如下&#xff0c;可对照注释进行理解&#xff1a;

1 (function($){
2 $.fn.czl_combobox &#61; function( options )
3 {
4 this.each( function()
5 {
6 var instance &#61; $.data( this , &#39;czl_combobox&#39; );
7 if( !instance )
8 {
9 //主体功能通过一个对象实现
10 $.data( this, &#39;czl_combobox&#39; , new $.ZLComboBox( options , this ) );
11 }
12 });//end of each
13
14 return this;
15 };
16 $.ZLComboBox &#61; function( options , element )
17 {
18 this.$el&#61; $( element );
19 this._init( options );
20 };
21
22 $.ZLComboBox.prototype &#61; {
23 _init : function( options )
24 {
25 //相关的控件
26 this.comboBox &#61; this.$el ;
27
28 //相关的HTML控件
29 this.cb_btn &#61; this.comboBox.children( &#39;.cb_btn&#39; ).eq(0);
30 this.cb_input &#61; this.comboBox.children( &#39;.cb_input&#39; ).eq(0);
31 this.cb_item &#61; this.comboBox.find( &#39;li&#39; );
32
33 //控件的状态&#xff0c;标记是否显示下拉列表
34 this.cb_showitem_status &#61; false ;
35
36 //初始化默认的值&#xff0c;默认选中最后一个选项
37 this.selected_index &#61; this.cb_item.length-1 ;
38 this.cb_input.html( this.cb_item.eq(this.selected_index).html() );
39
40 //注册响应事件
41 this._loadEvents();
42 },
43 _show_itemlist:function(){
44 if( this.cb_showitem_status &#61;&#61;&#61; false ){
45 this.comboBox.addClass( &#39;selected&#39; );
46 this.cb_showitem_status &#61; true;
47 }
48 else{
49 this.comboBox.removeClass( &#39;selected&#39; );
50 this.cb_showitem_status &#61; false;
51 }
52 return ;
53 },
54 _loadEvents:function(){
55 var _self &#61; this;
56 //1_单击下拉箭头
57 this.cb_btn.on( &#39;click&#39; , function( event ){
58 _self._show_itemlist( );
59 return ;
60 });
61 //2_单击编辑框&#xff0c;也同样进行下拉框的状态切换
62 this.cb_input.on( &#39;click&#39; , function( event ){
63 _self._show_itemlist( );
64 return ;
65 });
66 //3_单击选项
67 this.cb_item.on( &#39;click&#39; , function( event ){
68 var index &#61; $(this).index();
69 if( _self.selected_index !&#61;&#61; index ){
70 //设置选项的值
71 _self.cb_input.html( $(this).html() );
72
73 //设置当前选中的项
74 _self.selected_index &#61; index ;
75
76 //隐藏下拉框
77 _self._show_itemlist();
78 }
79 return ;
80 });
81 }
82 };
83 }(jQuery));

 

插件验证&#xff1a;

在index.html中&#xff0c;增加对插件调用的代码&#xff1a;

打开index.html网页&#xff0c;我们发现自定义的控件已经可以响应用户的单击事件&#xff0c;效果如下&#xff1a;

优化控件的可扩展性

有了前面的基础&#xff0c;接下来的理解就会比较简单。前面我们在分析控件的调用过程中&#xff0c;有一个参数options传到ZLComboBox对象中&#xff0c;但是&#xff0c;在最后的_init和_loadEvents方法中都没有用到过&#xff0c;那么&#xff0c;这个options的意义在哪里呢&#xff1f;

我们还是从业务的需求出发&#xff0c;然后再来考虑我们如何实现&#xff1a;

  • 如果将控件用在“幼儿教学”的应用中&#xff0c;用户选中一种水果之后&#xff0c;可以播放与这种水果相关的介绍视频。
  • 如果将控件用在“卖水果”的应用中&#xff0c;用户选中一种水果&#xff0c;可以显示这种水果的价格、产地等信息。

这就意味着&#xff0c;在不同的应用场景中&#xff0c;用户做出“选择水果”的操作时&#xff0c;触发的后续动作是不一样的&#xff0c;我们的控件应该支持这种操作才对。

如果在初始化控件的时候&#xff0c;传入一个“回调函数”&#xff0c;当事件触发时&#xff0c;调用一下这个传入的回调函数&#xff0c;那不就达到我们的目的了吗&#xff1f;这样&#xff0c;不同的业务场景&#xff0c;我们只要传入不同的回调函数即可。

回调函数是Javascript的最拿手的&#xff0c;现在&#xff0c;我们就来优化我们的控件&#xff0c;让它支持回调函数。

这里也先假设一个场景&#xff1a;

当用户选中一个选项之后&#xff0c;我们就将选项中水果的图片显示出来&#xff0c;这时候&#xff0c;调用这个控件的方式变成这样&#xff1a;

1 $(&#39;#fruit_box&#39;).czl_combobox( {
2 selectItemEvent:function( index ){
3 var html_content &#61; $( &#39;.item_list li img&#39; ).get( index ).outerHTML;
4 $(&#39;#result_box&#39;).html( html_content );
5 }
6 } );

注意到两点&#xff1a;

1. #fruit_box 为控件. zl_combobox对应的id&#xff0c;在同一个应用中可能存在多个zl_combobox控件&#xff0c;当要传入回调函数时&#xff0c;一般就用id去引用对应的控件元素&#xff0c;因为相同的控件&#xff0c;在不同的应用场景&#xff0c;行为是不同的&#xff0c;传入的回调函数也应该不同&#xff0c;所以不建议通过$(‘. zl_combobox’)一次性对所有的控件进行初始化。

2.传入的回调函数的名称是selectItemEvent&#xff0c;带有一个index 的参数。

 

现在&#xff0c;我们来优化控件的核心对象ZLComboBox中的内容&#xff1a;

1. 新增一个options成员&#xff0c;用来保存传入的参数对象&#xff1a;

_init:function( options ){//this. options &#61; options ;
}

2. 在下拉列表框中的选项单击事件中&#xff0c;增加对回调函数的调用&#xff1a;

//….//隐藏下拉框
_self._show_itemlist();//调用回调函数_self.options.selectItemEvent( index );

然后&#xff0c;我们再来验证一下效果&#xff0c;打开index.html&#xff0c;从下拉框中选中一个选项&#xff0c;效果如下&#xff1a;

 

至此&#xff0c;我们最初设定的目的是已经达成了。为了完整性&#xff0c;再补充一下控件“扩展性”的另外一个特征&#xff1a;默认值设定。

还是以之前的业务场景为例&#xff1a;如果用户没有传入回调函数&#xff0c;我们希望控件就把选中项的序号通过提示框显示出来。如果有传入会调用函数&#xff0c;就调用用户传入的回调函数。也就是说&#xff0c;给控件增加默认的行为&#xff0c;当调用时没有传入指定参数&#xff0c;就调用默认的值

现在我们就来实现控件的默认值设定&#xff1a;

1. 给ZLComboBox对象增加defaults成员&#xff0c;代码如下&#xff1a;

1 //默认值设置
2 $.ZLComboBox.defaults &#61; {
3 selectItemEvent:function( index ){
4 alert( index );
5 return ;
6 }
7 };

2. 在_init方法中&#xff0c;保存传入的options对象采用如下的方式&#xff1a;

this.options &#61; $.extend( true , {} , $.ZLComboBox.defaults , options );

这样&#xff0c;如果options中没有指定相关的成员&#xff0c;就调用defaults中的成员。这是jQuery插件处理传入参数的一种方式&#xff0c;$.extend为jQuery库定义的方法。 

优化控件的可用性

从理解语言特性来看&#xff0c;这部分内容与上一部分没有什么差异&#xff0c;我们只是从业务角度来看&#xff0c;对实现方式做一些区分。

回到我们控件的场景&#xff0c;本文实现的控件我们取名为ZLComboBox&#xff0c;ZL为前缀&#xff0c;显然&#xff0c;它的行为特征与标准的组合框控件是类似的&#xff0c;组合框控件最常见的使用方式就是在表单(Form)中&#xff0c;那么&#xff0c;我们的控件也应该支持在表单(Form)中使用。

如果ZLComboBox是作为表单的一个组件&#xff0c;那么&#xff0c;就需要在用户提交表单数据时&#xff0c;能够获取到用户到底选了哪个选项。从目前来看&#xff0c;似乎只能判断.cb_input容器中的内容&#xff0c;而这个内容是这个样子&#xff1a;

<img src&#61;"images/f_apple.png" /><span>苹果span>

显然&#xff0c;用户处理起来非常不方便。

也许你已经想到了&#xff0c;可以通过传入回调函数的方式&#xff0c;当用户选中一个选项之后&#xff0c;就将这个序号值(index)更新到某个隐藏的元素中&#xff0c;表单提交数据时&#xff0c;提交这个隐藏的中的值即可&#xff0c;这当然是一种处理方式。

其实&#xff0c;我们可以给控件的核心对象ZLComboBox增加一个方法getSelectedIndex&#xff0c;用来获取当前用户选中的项的序号&#xff0c;代码如下&#xff1a;

1 _loadEvents:function(){
2 //
3 },
4 getSelectedIndex:function(){
5 return this.selected_index;
6 }

这时候&#xff0c;控件的调用方式变成&#xff1a;

1 $(&#39;#fruit_box&#39;).czl_combobox( {
2 selectItemEvent:function( index ){
3 var html_content &#61; $( &#39;.item_list li img&#39; ).get( index ).outerHTML;
4 $(&#39;#result_box&#39;).html( html_content );
5 }
6 } );
7
8 //在表单提交前的数据处理中&#xff0c;取得用户选中项的序号
9 var index &#61; $(&#39;#fruit_box&#39;).data( ‘czl_combobox’ ). getSelectedIndex() ;

重点在第9行。

当然&#xff0c;你也许会觉得&#xff0c;这种方式还不如之前动态更新隐藏的方式自然&#xff0c;这里的主要目的是给大家一个特性解释&#xff0c;具体情况当然依据业务需要来确定。

另外&#xff0c;也许你已经发现了&#xff0c;每次调用我们自定义的控件&#xff0c;在HTML代码中都要写入一大堆内容&#xff0c;能不能在使用时HTML代码中仅仅定义

&#xff1f;然后将选项通过参数options传入&#xff0c;在ZLComboBox的_init方法中动态生产子部件呢&#xff1f;答案是&#xff1a;当然可以&#xff0c;就留作练习吧。

总结

通过前面的内容介绍&#xff0c;我们大致理解了自定义控件的意义&#xff0c;以及开发一个Web自定义控件的大致过程&#xff0c;希望能给大家带来一些启发。当然&#xff0c;我们的举例&#xff0c;实现方式都仅仅是为了讲解整个过程&#xff0c;在实际的开发过程中&#xff0c;除了业务诉求之外&#xff0c;还需要考虑其他方面的要求&#xff0c;比如性能方面&#xff1a;将整个控件库中CSS样式用到的背景图片优化成"雪碧"图&#xff0c;减少加载时间。或者安全性的优化&#xff1a;将某些插件的框架由&#39;伪类&#39;(new)调整为&#39;闭包&#39;模式&#xff0c;增强控件的安全性。

完整的示例代码&#xff0c;请单击此处下载。

感谢诸位捧场^_^&#xff5e;&#xff5e;


转载于:https://www.cnblogs.com/alai88/p/5281602.html


推荐阅读
author-avatar
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有