原生js插件封装

原生js插件封装

在进行开发时,有时候需要一个小功能(比如 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

})()

参考

原生 JavaScript 插件编写指南

Javascript 模块化编程(一):模块的写法

Javascript 模块化编程(二):AMD 规范

相关灵感

365bet吧 iOS 17.2电池续航怎么样 5款iPhone续航实测出炉
mobile365 250微克等于多少毫克

250微克等于多少毫克

📅 07-29 👁️ 6761
mobile365 请假多久才算休学

请假多久才算休学

📅 09-05 👁️ 8048
mobile365 薪字的成语大全集(薪的成语有哪些成语)(40个)
mobile365 王者荣耀凯怎么变钥匙了 王者荣耀中“凯”的钥匙之谜解析
mobile365 没有找到站点

没有找到站点

📅 07-19 👁️ 6360
365bet吧 足球体育彩票几点停止卖票,体彩足球几点关门
mobile365 一场改变中国的谋杀案:习近平薄熙来的权力之争影响深远
365bet吧 不休棋牌平台

不休棋牌平台

📅 08-27 👁️ 5586