插件,在多人项目开发的过程中,是个很好的工具。它能够将复用的部分,封装成一个公共的借口,只需要写一遍,就可以在多人项目中,按照一定规则进行使用。
开发一个插件需要完成以下几步:
1、定义在闭包中,并以一个立即执行函数进行开放。
2、将对象注册在window对象中,以开发接口供外界使用。
3、设置必要性的配置参数,以便根据配置参数的不同,执行不同的操作。
4、将公用方法,抽离出来,放在prototype原型链上。
现在,按照上述罗列的四步骤,一起探讨下,如何封装一个日期选择器插件吧。
需求背景:根据不同配置参数,需要动态可配的输入时间控件,再点击不同时间链接之后,返回一个时间值。时间值作为下次访问条件查询语句的参数。
技术难点:该需求,如果只封装成一个日期控件,方法较为简单,然后根据封装的控件,捕获点击事件,根据点击事件的值,进行相应操作。但,目前该插件封装出来,是给后台人员使用的,考虑到后端人员对前端的认识较为薄弱,因此想把点击后获取到的对一个标签值,当做一个string字符串,传递出来,以便后端人员进行下一步操作。该字符串的获取,需要有一个前提,即对日期控件进行点击,才读取值。因此该方法的难点就在于,如何将点击之后返回的值,直接return出来,并开接口传递到外界使用。
梳理步骤:设置自定义的日期数组、设置获取自定义配置参数方法、设置渲染的dom函数、设置回调的返回字符串函数、绑定 点击事件。
实际开发:
1、引入jquery插件和当前的JqDatepicker文件。
2、在JqDatepicker文件中,设置开发结构。
;(function($){
var JqDatepicker = function(JqDateObj){
};
JqDatepicker.prototype = {};
window.JqDatepicker = JqDatepicker;
})(window);
在该插件结构中,首先以(function($){})(window)立即执行函数形成闭包,前面的“;”是为了避免在引入文件末尾没分号情况下引起错误。利用函数形式,定义对象,并在prototype中预留函数定义入口。最后,将对象全局注册在window对象中。
3、在html文件中,定义默认配置参数,并实例化一个对象。
$(function(){
var settings = {
'startTime': '2017-09-20',
'endTime': '2018-04-21'
}
var ele = new JqDatepicker($('.class'),settins);
})
在实例化过程中,通过设置默认配置参数,进行实例化。但这种情况下,需要将settings传递到插件的对象方法中,在插件开发过程中,更推荐放在标签属性中,如下面所示默认配置参数以标签舒心形式传递:
<div class="jq-date" data-param='{
"startTime": "2017/06/21",
"endTime": "2017/07/01",
"tagDate": [
{"dayFlag":true,"date": "1"},
{"dayFlag":false, "date":"7"},
{"dayFlag":false, "date":"17"}
]
}'>
4、定义获取配置参数的方法,并扩展默认参数
//设置默认参数,日期选择器的开始时间和结束时间
this.settings = {
'startTime': '2019/03-21',
'endTime': '2019/08-32'
};
$.entend(this.settings,this.getSettings());
());
在prototype中定义getSettings函数
JqDatepicker.prototype = {
getSettings: function() {
var settings = this.JqdateObj.attr('data-param');
if (settings != "" || setting != undefined) {
return $.parseJson(settins)
} else {
return null;
}
5、保存并注册实例化的对象:在第二步中,将传入的实例化对象JqDateObj进行保存。使用this.JqDateObj = JqDateObj方式进行,这样能够保证在JqDatepicker对象中,保留了实例对象属性。
6、在index.html文件中,通过new对象的方式,不算最优方式,在一个页面需要多次调用插件的情况下,new的方式比较繁琐,因此在抽取插件的过程中,预留了一个JqDatepicker.init方法,尽心插件初始化。
JqDatepicker.init = function(JqDateObjs){
var _this_ = this;
new _this_(JqDateObjs);
}
这种init方式中,能够初始化一个实例对象,在调用过程中,可以直接使用JqDatepicker.init($('.class'));
7、根据设置的settings值,在prototype中增加设置dom节点的方法。并在对象中,进行引用。
setDom: function () {
var dom_conditions = this.settings;
var dom_str,dom_html="";
dom_conditions.tagDate.forEach(function (value,index) {
if ( value.dayFlag ) {
dom_str = "第"+value.date+"天";
} else {
dom_str = "过去"+value.date+"天";
}
dom_html = dom_html + '<a href="javascript:;" class="menu_date m-l-5" >' + dom_str + '</a>';
});
this.JqDateObj.append(dom_html);
}
8、dom节点设置好之后,可以为dom节点绑定click事件,并将事件之后的获取的参数,传递到方法中。在该方法中,将回调函数中的返回值,通过方法的形式进行返回。注意在这里需要将方法,显式的赋值给对象方法上。
this.JqDateObj.find(".menu_date").bind('click',function ( ) {
backString = $(this).html();
window.JqDatepicker.prototype.getBackString(backString);
});
9、在原型链中,定义getbackString方法。注意在该方法中,将从回调函数中获取的值,复制给JqDatepicker对象的params属性,这样在外部调用时,可以直接获取到该值。
getBackString: function (backString) {
JqDatepicker.params = backString;
return backString;
},
10、外界获取点击之后的响应值,该值通过点击事件触发。
$('.menu_date').click(function () {
console.info(JqDatepicker.params);
});
11、将插件封装为JQ形式,在该方法中,为了保持jquery的链式调用,需要return对象,外部调用则可以根据jquery方式调用。$('.class').JqDatepicker()
$.fn.extend({
JqDatepicker: function () {
new JqDatepicker($(this));
return this;
}
});
至此,该插件就封装完毕了。后续将要利用原生js方式,继续将该插件进行封装