在进行开发时,有时候需要一个小功能(比如jsonp),但是却有一个很大的库(jQuery)提供了这个功能。
为了保证代码的简洁性,肯定是打算自己造轮子,下面是进行原生JavsScript插件的一些步骤
要求
首先一个合格的插件要有下面几个要求
-
插件自身的作用域与用户当前的作用域相互独立,也就是插件内部的私有变量不能影响使用者的环境变量
-
插件需具备默认设置参数
-
插件除了具备已实现的基本功能外,需提供部分API,使用者可以通过该API修改插件功能的默认参数,从而实现用户自定义插件效果
-
插件需提供监听入口,及针对指定元素进行监听,使得该元素与插件响应达到插件效果
-
插件支持链式调用
步骤
显然,把所有功能都写在一个单纯的函数内是无法满足上述要求的
插件全局函数
实现私有作用域,最好的办法就是使用闭包。可以把插件当做一个函数,插件内部的变量及函数的私有变量,为了在调用插件后依旧能使用其功能,闭包的作用就是延长函数(插件)内部变量的生命周期,使得插件函数可以重复调用,而不影响用户自身作用域。
故需将插件的所有功能写在一个立即执行函数中:
(function () { //插件所有功能都写在这个函数下 })();
插件默认参数
插件的主要功能可以总结至几个关键参数,通过这几个关键参数即可修改插件的主要功能,也是第三步API设置的关键参数。
将默认参数放置在全局函数的最前面,参数变量名为options,通过对象字面量进行赋值:
var options = { key1: para1, key2: para2, key3: para3, ... keyn: paran }
插件API、参数设置和监听
因为API指向的是使用者,故需要在用户调用插件时将API暴露给用户,因用户API时是通过插件提供的名字进行使用,故将API设置为Object类型,用户就可以通过调用API的key进行使用,具体的代码如下:
var api = { config: function (ops) { //.... return this;//便于链式调用 }, listen: function listen(elem) { //... return this; }, feature1: function() { //... }, feature2: function() { //... } } this.pluginName = api;
代码框架
根据上述步骤
;(function () { //配置-私有的 var options = { .... } //私有的函数,供内部调用 function doSomething() { ... } //API var api = { //配置参数 config: function (opts) { if(!opts) return options; for(var key in opts) { options[key] = opts[key]; } return this; }, //设置监听 listen: function listen(elem) { if (typeof elem === 'string') { var elems = document.querySelectorAll(elem), i = elems.length; while (i--) { listen(elems[i]); } return } //调用内部的函数 doSomething(elem, options.splitter); return this; } } //this==window this.myplugin = api; })();
对象
当然了,通过对象的创建也能很好的实现上述的效果
一般情况下,闭包函数写的插件的配置是config之后是公共的了,多次调用插件用的是同一个配置
如果需要手动的对element添加不同的配置的推荐使用对象的方式创建,new对象是传入不同的配置,再把对象应用于不同的element
总之闭包函数写的插件体现在公用,通过对象写的插件体现在私用,比如分页插件,一个页面可能有多个分页插件,采用不同的配置,不同的监听效果,,用该使用多个对象才能对多个分页插件进行互不干扰的操作
DEMO
下面是一个简单的jsonp插件代码
;(function () { //主要函数 function main(options,callbackfunc){ //产生一个随机函数名 var callbackName = ('jsonp_' + Math.random()).replace(".", ""); //参数添加到url中 var newUrl = addUrlParm(options.url,options.parm); if(!newUrl.endsWith('?')){ newUrl = newUrl+"&"; } newUrl=newUrl+options.callbackName+"="+callbackName; //创建 script 标签并加入到页面中 var oHead = document.getElementsByTagName('head')[0]; var oS = document.createElement('script'); oHead.appendChild(oS); //创建jsonp回调函数 window[callbackName] = function (json) { oHead.removeChild(oS); clearTimeout(oS.timer); window[callbackName] = null; callbackfunc(json); }; //超时处理 oS.timer = setTimeout(function () { window[callbackName] = null; oHead.removeChild(oS); callbackfunc(null); }, options.time); //开始请求 oS.src = newUrl; } function addUrlParm(url,parm){ var arr = []; for (var name in parm){ arr.push(name + '=' + parm[name]); } return url+"?"+arr.join('&'); } var api = { execute:function(opt,callbackfunc){ options = { parm:{}, time:3000, callbackName:'callback' }; if (!opt.url&&!opt.callback) { console.error("参数不合法...."); return; }else{ options.url=opt.url; } options.parm=opt.parm||options.parm; options.time=opt.time||options.time; options.callbackName=opt.callbackName||options.callbackName; main(options,callbackfunc); } }; //曝露方法 this.jsonp = api; })();
注:本文内容来自互联网,旨在为开发者提供分享、交流的平台。如有涉及文章版权等事宜,请你联系站长进行处理。