基于原生JS封裝的Modal對話框插件的示例代碼
基于原生JS封裝Modal對話框插件,具體內(nèi)容如下所示:
原生JS封裝Modal對話框插件,個人用來學(xué)習(xí)原理與思想,只有簡單的基本框架的實(shí)現(xiàn),可在此基礎(chǔ)上添加更多配置項(xiàng)
API配置
//基本語法 let modal = ModalPlugin({ //提示的標(biāo)題信息 title:'系統(tǒng)提示', //內(nèi)容模板 字符串 /模板字符串/DOM元素對象 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不會出錯,會返回undefined module.exports = ModalPlugin;//CommonJS規(guī)范,只有在webpack環(huán)境下才支持 } })()
使用對象和函數(shù)創(chuàng)建實(shí)例
想使用創(chuàng)建對象的方式new ModalPlugin()
創(chuàng)建實(shí)例或當(dāng)做普通函數(shù)執(zhí)行ModalPlugin()
,創(chuàng)建實(shí)例,需要這樣做
(function () { function ModalPlugin() { return new init() } //想使用創(chuàng)建對象的方式`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不會出錯,會返回undefined module.exports = ModalPlugin;//CommonJS規(guī)范,只有在webpack環(huán)境下才支持 } })()
配置項(xiàng)
//封裝插件的時候,需要支持很多配置項(xiàng),有的配置項(xiàng)不傳遞有默認(rèn)值,此時我們千萬不要一個個定義形參,用對象的方式傳形參,好處是可以不傳,而且可以不用考慮順序 function ModalPlugin(options) { return new init(options) } //想使用創(chuàng)建對象的方式創(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,每一次動態(tài)插入,都會導(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 }
對參數(shù)進(jìn)行處理
creatDom() { let {title, template, buttons} = this.options //如果用creatElement插入DOM,每一次動態(tài)插入,都會導(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 () { //封裝插件的時候,需要支持很多配置項(xiàng),有的配置項(xiàng)不傳遞有默認(rèn)值,此時我們千萬不要一個個定義形參,用對象的方式傳形參,好處是可以不穿,而且可以不用考慮順序 function ModalPlugin(options) { return new init(options) } //想使用創(chuàng)建對象的方式創(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,每一次動態(tài)插入,都會導(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í)例上: 在原型的各個方法中,只要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不會出錯,會返回undefined module.exports = ModalPlugin;//CommonJS規(guī)范,只有在webpack環(huán)境下才支持 } })()
使用
使用時需要引入modalpugin.js
和modalpugin.css
使用示例1:
//使用: const modal1 = ModalPlugin({ //提示的標(biāo)題信息 title: '系統(tǒng)提示', //內(nèi)容模板 字符串 /模板字符串/DOM元素對象 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對話框插件的示例代碼的文章就介紹到這了,更多相關(guān)JS封裝Modal對話框插件內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- JS庫particles.js創(chuàng)建超炫背景粒子插件(附源碼下載)
- JavaScript枚舉選擇jquery插件代碼實(shí)例
- 構(gòu)建一個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用法簡單示例
- viewer.js一個強(qiáng)大的基于jQuery的圖像查看插件(支持旋轉(zhuǎn)、縮放)
- Js視頻播放器插件Video.js使用方法詳解
- 創(chuàng)建與框架無關(guān)的JavaScript插件
相關(guān)文章
利用10行js代碼實(shí)現(xiàn)上下滾動公告效果
這篇文章主要給大家介紹了關(guān)于利用10行js代碼實(shí)現(xiàn)滾動公告效果的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起看看吧。2017-12-12純JavaScript 實(shí)現(xiàn)flappy bird小游戲?qū)嵗a
這篇文章主要介紹了純JavaScript 實(shí)現(xiàn)flappy bird小游戲?qū)嵗a,b本文分七大步驟給大家介紹,非常不錯,具有參考借鑒價值,需要的朋友可以參考下2016-09-09JavaScript之通過年月獲取月份的天數(shù)、日期格式化、時間、補(bǔ)零、Date、toLocaleString、Intl、
這篇文章主要介紹了JavaScript之通過年月獲取月份的天數(shù)、日期格式化、時間、補(bǔ)零、Date、toLocaleString、Intl、DateTimeFormat、format的相關(guān)知識,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友參考下吧2024-03-03