i.为GPU一体机项目开发的一款下拉树插件ii.记录第一次开发jquery插件的过程
iii.wisdomTree的基本用法
jquery插件的开发模式
-
一般而言,有三种
-
$.extend()
来扩展jQuery -
$.fn
向jQuery添加新的方法 -
$.widget()
应用jQuery UI的部件工厂方式创建
-
$.extend()
-
$.extend()
函数用于将一个或多个对象的内容合并到目标对象并返回目标对象(第一个对象),有点写轮眼的味道,下面试试它的用法 -
$.extend()
基本用法,可以看出$.extend()
返回对象中的所有属性(可理解为属性求和),且属性值向后取值
对象属性相同,属性值不同
$.extend({name:'yh',num:9},{name:'ylone',num:22},{name:'ylone666',num:666})
?
{name: "ylone666", num: 666}
对象属性不同,且目标对象<其他对象
$.extend({name:'yh',num:9},{name:'ylone',num:22,cool:true},{name:'ylone666',num:666})
?
{name: "ylone666", num: 666, cool: true}
对象属性不同,且目标对象>其他对象
$.extend({name:'yh',num:9,cool:true},{name:'ylone',num:22},{name:'ylone666',num:666})
?
{name: "ylone666", num: 666, cool: true}
对象属性各不相同
$.extend({name:'yh',cool:true},{num:22},{run:199})
?
{name: "yh", cool: true, num: 22, run: 199}
-
$.extend()
特殊用法
将对象合并到jquery的全局对象中,可以在全局对其进行调用
$.extend({test:function(){console.log("test")}})
?
$.test ? ƒ (){console.log("test")}
$.test() ? test
重载原型,选择进行深度拷贝,第一个参数配置是否进行深度拷贝,可以看出,深度拷贝对对象里面的对象(即所有属性及其子属性)都进行了 $.extend()
操作
//深度拷贝
$.extend( true, {},
{ name: "yh", location: {cool: false,num:"1"} },
{ last: "ylone", location: {state: "well",county:"China", cool: true} } );
?
{name: "ylone", location: {cool:true,county:"China",num:"1",state:"well"}}
//非深度拷贝
$.extend( false, {},
{ name: "yh", location: {cool: false,num:"1"} },
{ name: "ylone", location: {state: "well",county:"China", cool: true} } );
?
{name: "ylone", location: {cool:true,county:"China",state:"well"}}
$.fn
-
$.fn
是指jquery的命名空间,加上fn上的方法及属性,会对jquery实例每一个有效,可以简单理解为在全局范围写函数方法
如下相当于是对jquery扩展了一个wsTree方法,那么后面你的每一个jquery实例都可以引用这个方法了.
那么你可以这样子:$("#div").wsTree();
$.fn.wsTree = function(options) {
var wisdomTree = new WISDOMTREE(this, options);
return wisdomTree.init();
}
查看jquery源码, jQuery.fn = jQuery.prototype = {...}
,向 $(全局对象)添加属性和方法,通过 $(dom).jquery
即可看到jquery的版本号
jQuery.fn = jQuery.prototype = {
// The current version of jQuery being used
jquery: version,
constructor: jQuery,
// The default length of a jQuery object is 0
length: 0,
toArray: function() {
return slice.call( this );
}...
面向对象
- 这次开发过程对于面向对象的三个基本特性(封装,继承,多态)有了更深的理解
- 使用面对对象的开发模式,方便管理,更重要的是不会污染外部的命名空间,实际上,我们只需要在全局命名空间上声明一个对象初始化的方法,然后将函数和变量写在对象的内部,变成对象的方法和对象的属性就好了
自调用匿名函数包裹代码块
- 一个自我调用的匿名函数在创建时自动,立即运行,并且没有名字,因此被称为自调用匿名函数
- 基本格式:
;(fucntion($, window, document, undefined){ code... })(jQuery, window, document)
- 作用原理:函数可以形成一个作用域,域内的代码是无法被外界访问的,如果我们将自己的代码放入一个函数中,那么就不会污染全局命名空间,同时不会和别的代码冲突
- 函数前的
;
作用:自调用匿名函数与上一段代码相连,如果上一段代码没有以分号结束,而我们又没有主动地加上分好,那么会导致函数编译出错 - 将系统变量以参数形式传递到插件内部,可以提高对系统变量的访问速度,其中
undefined
的妙处在于:为了得到没有被修改的undefined
,我们并没有传递这个参数,但却在接收时接收了它,因为实际并没有传,所以undefined
那个位置接收到的就是真实的undefined
wisdomTree开发过程
在全局命名空间添加声明对象的方法,options
表示在使用插件,创建对象时的一些配置项, this
表示选择的元素
$.fn.wsTree = function(options) {
var wisdomTree = new WISDOMTREE(this, options);
return wisdomTree;
}
接着,在 WISDOMTREE
对象内添加一些默认属性,$.extend({}, this.defaults, opt)
使用 {}
来保护默认配置项,将选择元素与配置放在 this(它代表函数运行时,自动生成的一个内部对象,只能在函数内部使用 )
中
var WISDOMTREE = function(ele, opt) {
this.element = ele,
this.defaults = {
'data': '', //数据
'buttonValue': 'WISDOMTREE', //标题栏提示
'buttonStyle': { //标题栏样式
"width": "100px",
"border": "1px solid #999",
"height": "26px",
"line-height": "26px",
"text-align": "center"
},
'conStyle': { //下拉框样式
"width": "220px",
"max-height": "600px",
"border": "1px solid #222"
},
'treeHeight': null, //树的高度
'fontColor': '#000', //树字体颜色
'fontBackgrd': '#fff', //树字体背景颜色
'chkType': 'checkbox', //选择方式,单选(radio)或者多选(checkbox)
'chkRela': { "Y": "ps", "N": "ps" }, //父子关联关系,
'rootParam': ['name'], //父节点属性
'seedParam': ['name'], //子节点属性
'rootIcon': null, //父节点图标样式
'seedIcon': null, //子节点图标样式
'rootNoCheck': false, //顶级父节点是否可以选中
'ancientId': true, //是否获取祖先元素的ID
'onDownCallBack': null, //收起下拉树的回调
'isQuery': false, //是否显示搜索框
'queryOpen': false, //是否展示搜索框
'queryCallBack': null, //搜索事件回调
'queryParam': {} //搜索的参数
},
this.options = $.extend(true, {}, this.defaults, opt);
}
最后,向 WISDOMTREE
对象中添加一些方法,一套插件三连,带走~
WISDOMTREE.prototype = {
//初始化
init: function() {
var $SELMAIN = this.element.attr("id");
...
},
//获取值
get: function()
...
}
- 如果你喜欢,可以对插件内容进行压缩,毕竟js文件的大小会对性能产生影响
踩过的坑
- 要理解和注意全局命名空间,最初我自己在全局定义了
init()
方法,控制台一直报错 -
理解面向对象的三大特性,最初我在
$.fn.wstree
内返回的是wisdomTree.init()
方法,这样做的坏处在于:- 没有充分利用面向对象的思维 - 污染了全局命名空间,因为要用到对象中封装的方法,还需要 `$.fn` 一下 - 当你要用对象内封装的 `get()` 时,还需要将关键的配置项再传一次,否则就会以默认配置项进行处理
- 对于
WISDOMTREE.prototype
里面this
对象相当于全局变量
基本用法
- 具体参考wisdomTree,里面对插件配置及使用方法进行了详细的介绍