基于原生JS封裝的Modal對(duì)話框插件的示例代碼
基于原生JS封裝Modal對(duì)話框插件,具體內(nèi)容如下所示:
原生JS封裝Modal對(duì)話框插件,個(gè)人用來學(xué)習(xí)原理與思想,只有簡(jiǎn)單的基本框架的實(shí)現(xiàn),可在此基礎(chǔ)上添加更多配置項(xiàng)
API配置
//基本語法
let modal = ModalPlugin({
//提示的標(biāo)題信息
title:'系統(tǒng)提示',
//內(nèi)容模板 字符串 /模板字符串/DOM元素對(duì)象
template:null,
//自定義按鈕信息
buttons:[{
//按鈕文字
text:'確定',
click(){
//this:當(dāng)前實(shí)例
}
}]
})
modal.open()//=>打開
modal.close()//=>關(guān)閉
//基于發(fā)布訂閱,實(shí)現(xiàn)回調(diào)函數(shù)的監(jiān)聽
modal.on('input/open/close/dragstart/dragmove/dragend',[func])
modal.fire(...)
modal.off(...)
Modal插件核心功能的開發(fā)
導(dǎo)出
(function () {
function ModalPlugin() {
return
}
// 瀏覽器直接導(dǎo)入,這樣的方法是暴露到全局的
window.ModalPlugin = ModalPlugin;
//如果還需要支持ES6Module/CommonJS模塊導(dǎo)入規(guī)范,在react項(xiàng)目當(dāng)中,vue項(xiàng)目當(dāng)中也想用
if (typeof module !== 'undefined' && module.exports !== 'undefined') {//如果module不存在,typeof不會(huì)出錯(cuò),會(huì)返回undefined
module.exports = ModalPlugin;//CommonJS規(guī)范,只有在webpack環(huán)境下才支持
}
})()
使用對(duì)象和函數(shù)創(chuàng)建實(shí)例
想使用創(chuàng)建對(duì)象的方式new ModalPlugin()創(chuàng)建實(shí)例或當(dāng)做普通函數(shù)執(zhí)行ModalPlugin(),創(chuàng)建實(shí)例,需要這樣做
(function () {
function ModalPlugin() {
return new init()
}
//想使用創(chuàng)建對(duì)象的方式`new ModalPlugin()`創(chuàng)建實(shí)例或當(dāng)做普通函數(shù)執(zhí)行`ModalPlugin()`,創(chuàng)建實(shí)例,需要這樣做
//類的原型: 公共的屬性方法
ModalPlugin.prototype = {
constructor: ModalPlugin
}
function init() {}
init.prototype = ModalPlugin.prototype;
// 瀏覽器直接導(dǎo)入,這樣的方法是暴露到全局的
window.ModalPlugin = ModalPlugin;
//如果還需要支持ES6Module/CommonJS模塊導(dǎo)入規(guī)范,在react項(xiàng)目當(dāng)中,vue項(xiàng)目當(dāng)中也想用
if (typeof module !== 'undefined' && module.exports !== 'undefined') {//如果module不存在,typeof不會(huì)出錯(cuò),會(huì)返回undefined
module.exports = ModalPlugin;//CommonJS規(guī)范,只有在webpack環(huán)境下才支持
}
})()
配置項(xiàng)
//封裝插件的時(shí)候,需要支持很多配置項(xiàng),有的配置項(xiàng)不傳遞有默認(rèn)值,此時(shí)我們千萬不要一個(gè)個(gè)定義形參,用對(duì)象的方式傳形參,好處是可以不傳,而且可以不用考慮順序
function ModalPlugin(options) {
return new init(options)
}
//想使用創(chuàng)建對(duì)象的方式創(chuàng)建實(shí)例new ModalPlugin()或當(dāng)做普通函數(shù)執(zhí)行也能創(chuàng)建實(shí)例ModalPlugin(),需要這樣做
ModalPlugin.prototype = {
constructor: ModalPlugin
}
function init(options) {
//接下來將所有的操作全部寫在init里面
//參數(shù)初始化:傳遞進(jìn)來的配置項(xiàng)替換默認(rèn)的配置項(xiàng)
options = Object.assign({
title:'系統(tǒng)提示',
template:null,
frag:true,
buttons:[{
text:'確定',
click(){
}
}]
},options)
}
命令模式init()執(zhí)行邏輯

創(chuàng)建DOM
//創(chuàng)建DOM結(jié)構(gòu)
creatDom(){
//如果用creatElement插入DOM,每一次動(dòng)態(tài)插入,都會(huì)導(dǎo)致DOM的回流,非常消耗性能,所以最外面使用createElement創(chuàng)建,內(nèi)部使用字符串的方式拼寫進(jìn)去,創(chuàng)建好了之后放到最外層的容器當(dāng)中,只引起一次回流
let frag = document.createDocumentFragment()
let dpnDialog = document.createElement('div')
dpnDialog.className = 'dpn-dialog'
dpnDialog.innerHTML = `
<div class="dpn-title">
系統(tǒng)溫馨提示
<i class="dpn-close"></i>
</div>
<div class="dpn-content">
</div>
<div class="dpn-handle">
<button>確定</button>
<button>取消</button>
</div>`
frag.appendChild(dpnDialog)
let dpnModel = document.createElement('div')
dpnModel.className = 'dpn-model'
frag.appendChild(dpnModel)
document.body.appendChild(frag)//使用frag只需要往頁面中插入一次,減少回流次數(shù)
frag = null
this.dpnDialog = dpnDialog//掛載到實(shí)例上,便于其他方法的控制隱藏,并且是私有的實(shí)例,
this.dpnModel = dpnModel
}
對(duì)參數(shù)進(jìn)行處理

creatDom() {
let {title, template, buttons} = this.options
//如果用creatElement插入DOM,每一次動(dòng)態(tài)插入,都會(huì)導(dǎo)致DOM的回流,非常消耗性能,所以最外面使用createElement創(chuàng)建,內(nèi)部使用字符串的方式拼寫進(jìn)去,創(chuàng)建好了之后放到最外層的容器當(dāng)中,只引起一次回流
let frag = document.createDocumentFragment()
let dpnDialog = document.createElement('div')
dpnDialog.className = 'dpn-dialog'
dpnDialog.innerHTML = `
<div class="dpn-title">
${title}
<i class="dpn-close">X</i>
</div>
<div class="dpn-content">
${template && typeof template === 'object' && template.nodeType === 1
? template.outerHTML
: template}
</div>
${buttons.length > 0
? `<div class="dpn-handle">
${buttons.map((item, index) => {
return `<button index="${index}">${item.text}</button>`
}).join('')}
</div>`
: ''
}
`
frag.appendChild(dpnDialog)
let dpnModel = document.createElement('div')
dpnModel.className = 'dpn-model'
frag.appendChild(dpnModel)
document.body.appendChild(frag)//使用frag只需要往頁面中插入一次,減少回流次數(shù)
frag = null
this.dpnDialog = dpnDialog//掛載到實(shí)例上,便于其他方法的控制隱藏,并且是私有的實(shí)例,
this.dpnModel = dpnModel
},
控制隱藏與顯示
//控制他顯示
open() {
this.dpnDialog.style.display = 'block'
this.dpnModel.style.display = 'block'
},
//控制隱藏
close() {
this.dpnDialog.style.display = 'none'
this.dpnModel.style.display = 'none'
}
基于事件委托處理點(diǎn)擊事件

init() {
this.creatDom()
//基于事件委托,實(shí)現(xiàn)點(diǎn)擊事件的處理
this.dpnDialog.addEventListener('click', (ev)=>{
let target = ev.target,
{tagName,className}= target
console.log([target])
//點(diǎn)擊的關(guān)閉按鈕
if(tagName==='I'&&className.includes('dpn-close')){
this.close()
return
}
//點(diǎn)擊的是底部按鈕
if(tagName==='BUTTON' && target.parentNode.className.includes('dpn-handle')){
let index = target.getAttribute('index')
//讓傳過來的函數(shù)執(zhí)行,并且函數(shù)中的this還必須是當(dāng)前實(shí)例
let func = this.options.buttons[index]['click']
if(typeof func==='function'){
func.call(this)
}
return
}
})
},
基于發(fā)布訂閱實(shí)現(xiàn)回調(diào)函數(shù)的監(jiān)聽(生命周期)



//使用:


完整代碼
//modalplugin.js
(function () {
//封裝插件的時(shí)候,需要支持很多配置項(xiàng),有的配置項(xiàng)不傳遞有默認(rèn)值,此時(shí)我們千萬不要一個(gè)個(gè)定義形參,用對(duì)象的方式傳形參,好處是可以不穿,而且可以不用考慮順序
function ModalPlugin(options) {
return new init(options)
}
//想使用創(chuàng)建對(duì)象的方式創(chuàng)建實(shí)例new ModalPlugin()或當(dāng)做普通函數(shù)執(zhí)行也能創(chuàng)建實(shí)例ModalPlugin(),需要這樣做
ModalPlugin.prototype = {
constructor: ModalPlugin,
//相當(dāng)于大腦,可以控制先干什么在干什么(命令模式)
init() {
//創(chuàng)建DOM結(jié)構(gòu)
this.creatDom()
//基于事件委托,實(shí)現(xiàn)點(diǎn)擊事件的處理
this.dpnDialog.addEventListener('click', (ev) => {
let target = ev.target,
{tagName, className} = target
//點(diǎn)擊的關(guān)閉按鈕
if (tagName === 'I' && className.includes('dpn-close')) {
this.close()
return
}
//點(diǎn)擊的是底部按鈕
if (tagName === 'BUTTON' && target.parentNode.className.includes('dpn-handle')) {
let index = target.getAttribute('index')
//讓傳過來的函數(shù)執(zhí)行,并且函數(shù)中的this還必須是當(dāng)前實(shí)例
let func = this.options.buttons[index]['click']
if (typeof func === 'function') {
func.call(this)
}
return
}
})
this.fire('init')//通知init方法執(zhí)行成功
},
//創(chuàng)建DOM結(jié)構(gòu)
creatDom() {
let {title, template, buttons} = this.options
//如果用creatElement插入DOM,每一次動(dòng)態(tài)插入,都會(huì)導(dǎo)致DOM的回流,非常消耗性能,所以最外面使用createElement創(chuàng)建,內(nèi)部使用字符串的方式拼寫進(jìn)去,創(chuàng)建好了之后放到最外層的容器當(dāng)中,只引起一次回流
let frag = document.createDocumentFragment()
let dpnDialog = document.createElement('div')
dpnDialog.className = 'dpn-dialog'
dpnDialog.innerHTML = `
<div class="dpn-title">
${title}
<i class="dpn-close">X</i>
</div>
<div class="dpn-content">
${template && typeof template === 'object' && template.nodeType === 1
? template.outerHTML
: template}
</div>
${buttons.length > 0
? `<div class="dpn-handle">
${buttons.map((item, index) => {
return `<button index="${index}">${item.text}</button>`
}).join('')}
</div>`
: ''
}
`
frag.appendChild(dpnDialog)
let dpnModel = document.createElement('div')
dpnModel.className = 'dpn-model'
frag.appendChild(dpnModel)
document.body.appendChild(frag)//使用frag只需要往頁面中插入一次,減少回流次數(shù)
frag = null
this.dpnDialog = dpnDialog//掛載到實(shí)例上,便于其他方法的控制隱藏,并且是私有的實(shí)例,
this.dpnModel = dpnModel
},
//控制他顯示
open() {
this.dpnDialog.style.display = 'block'
this.dpnModel.style.display = 'block'
this.fire('open')//通知open方法執(zhí)行成功
},
//控制隱藏
close() {
this.dpnDialog.style.display = 'none'
this.dpnModel.style.display = 'none'
this.fire('close')//通知close方法執(zhí)行成功
},
//on向事件池中訂閱方法
on(type, func) {
let arr = this.pond[type]
if(arr.includes(func)) return
arr.push(func)
},
//通知事件池中的方法執(zhí)行
fire(type) {
let arr = this.pond[type]
arr.forEach(item => {
if(typeof item ==='function'){
item.call(this)
}
})
}
}
function init(options) {
//接下來將所有的操作全部寫在init里面
//參數(shù)初始化:傳遞進(jìn)來的配置項(xiàng)替換默認(rèn)的配置項(xiàng)
options = Object.assign({
title: '系統(tǒng)提示',
template: null,
frag: true,
buttons: [{}]
}, options)
//把信息掛載到實(shí)例上: 在原型的各個(gè)方法中,只要this是實(shí)例,都可以調(diào)用到這些信息
this.options = options;
this.pond = {
init: [],
close: [],
open: []
}
this.init()
}
init.prototype = ModalPlugin.prototype;
// 瀏覽器直接導(dǎo)入,這樣的方法是暴露到全局的
window.ModalPlugin = ModalPlugin;
//如果還需要支持ES6Module/CommonJS模塊導(dǎo)入規(guī)范,在react項(xiàng)目當(dāng)中,vue項(xiàng)目當(dāng)中也想用
if (typeof module !== 'undefined' && module.exports !== 'undefined') {//如果module不存在,typeof不會(huì)出錯(cuò),會(huì)返回undefined
module.exports = ModalPlugin;//CommonJS規(guī)范,只有在webpack環(huán)境下才支持
}
})()
使用
使用時(shí)需要引入modalpugin.js和modalpugin.css
使用示例1:
//使用:
const modal1 = ModalPlugin({
//提示的標(biāo)題信息
title: '系統(tǒng)提示',
//內(nèi)容模板 字符串 /模板字符串/DOM元素對(duì)象
template: null,
//自定義按鈕信息
buttons: [{
//按鈕文字
text: '確定',
click() {
//this:當(dāng)前實(shí)例
this.close()
}
}, {
//按鈕文字
text: '取消',
click() {
//this:當(dāng)前實(shí)例
this.close()
},
}]
})
modal1.on('open',()=>{
console.log('我被打開了1')
})
modal1.on('open',()=>{
console.log('我被打開了2')
})
modal1.on('close',()=>{
console.log('我被關(guān)閉了')
})
modal1.open()
使用示例2:

github
完整代碼github
到此這篇關(guān)于基于原生JS封裝的Modal對(duì)話框插件的示例代碼的文章就介紹到這了,更多相關(guān)JS封裝Modal對(duì)話框插件內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- JS庫particles.js創(chuàng)建超炫背景粒子插件(附源碼下載)
- JavaScript枚舉選擇jquery插件代碼實(shí)例
- 構(gòu)建一個(gè)JavaScript插件系統(tǒng)
- vue中jsonp插件的使用方法示例
- js實(shí)現(xiàn)無縫輪播圖插件封裝
- js實(shí)現(xiàn)拾色器插件(ColorPicker)
- 原生js實(shí)現(xiàn)日期選擇插件
- VSCode插件開發(fā)全攻略之package.json詳解
- jQuery 圖片查看器插件 Viewer.js用法簡(jiǎn)單示例
- viewer.js一個(gè)強(qiáng)大的基于jQuery的圖像查看插件(支持旋轉(zhuǎn)、縮放)
- Js視頻播放器插件Video.js使用方法詳解
- 創(chuàng)建與框架無關(guān)的JavaScript插件
相關(guān)文章
TypeScript轉(zhuǎn)javaScript的方法示例
本文主要介紹了TypeScript轉(zhuǎn)javaScript的方法示例,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2022-06-06
解決JSON.stringify()自動(dòng)將中文轉(zhuǎn)譯成unicode的問題
下面小編就為大家分享一篇解決JSON.stringify()自動(dòng)將中文轉(zhuǎn)譯成unicode的問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2018-01-01
簡(jiǎn)單了解JavaScript arguement原理及作用
這篇文章主要介紹了簡(jiǎn)單了解JavaScript arguement原理及作用,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-05-05
快速學(xué)習(xí)JavaScript的6個(gè)思維技巧
在這篇文章中,我將介紹六個(gè)思維技巧來幫助你更快地學(xué)習(xí)JavaScript,并成為一個(gè)更快樂、更富有成效的程序員。2015-10-10
JavaScript使用math.js進(jìn)行精確計(jì)算操作示例
這篇文章主要介紹了JavaScript使用math.js進(jìn)行精確計(jì)算操作,結(jié)合實(shí)例形式分析了開源庫math.js進(jìn)行高精度數(shù)學(xué)運(yùn)算相關(guān)操作技巧,需要的朋友可以參考下2018-06-06

