基于原⽣JS封装的Modal对话框插件的⽰例代码基于原⽣JS封装Modal对话框插件,具体内容如下所⽰:
原⽣JS封装Modal对话框插件,个⼈⽤来学习原理与思想,只有简单的基本框架的实现,可在此基础上添加更多配置项
API配置
//基本语法
let modal = ModalPlugin({
//提⽰的标题信息
原生js和js的区别title:'系统提⽰',
//内容模板字符串 /模板字符串/DOM元素对象
template:null,
//⾃定义按钮信息
buttons:[{
//按钮⽂字
text:'确定',
click(){
//this:当前实例
}
}]
})
modal.open()//=>打开
modal.close()//=>关闭
//基于发布订阅,实现回调函数的监听
<('input/open/close/dragstart/dragmove/dragend',[func])
modal.fire(...)
modal.off(...)
Modal插件核⼼功能的开发
导出
(function () {
function ModalPlugin() {
return
}
// 浏览器直接导⼊,这样的⽅法是暴露到全局的
window.ModalPlugin = ModalPlugin;
/
/如果还需要⽀持ES6Module/CommonJS模块导⼊规范,在react项⽬当中,vue项⽬当中也想⽤
if (typeof module !== 'undefined' && ports !== 'undefined') {//如果module不存在,typeof不会出错,会返回undefined
}
})()
使⽤对象和函数创建实例
想使⽤创建对象的⽅式new ModalPlugin()创建实例或当做普通函数执⾏ModalPlugin(),创建实例,需要这样做
(function () {
function ModalPlugin() {
return new init()
}
//想使⽤创建对象的⽅式`new ModalPlugin()`创建实例或当做普通函数执⾏`ModalPlugin()`,创建实例,需要这样做
//类的原型: 公共的属性⽅法
ModalPlugin.prototype = {
constructor: ModalPlugin
}
function init() {}
init.prototype = ModalPlugin.prototype;
// 浏览器直接导⼊,这样的⽅法是暴露到全局的
window.ModalPlugin = ModalPlugin;
//如果还需要⽀持ES6Module/CommonJS模块导⼊规范,在react项⽬当中,vue项⽬当中也想⽤
if (typeof module !== 'undefined' && ports !== 'undefined') {//如果module不存在,typeof不会出错,会返回undefined
}
})()
配置项
//封装插件的时候,需要⽀持很多配置项,有的配置项不传递有默认值,此时我们千万不要⼀个个定义形参,⽤对象的⽅式传形参,好处是可以不传,⽽且可以不⽤考虑顺序
function ModalPlugin(options) {
return new init(options)
}
//想使⽤创建对象的⽅式创建实例new ModalPlugin()或当做普通函数执⾏也能创建实例ModalPlugin(),
需要这样做
ModalPlugin.prototype = {
constructor: ModalPlugin
}
function init(options) {
//接下来将所有的操作全部写在init⾥⾯
//参数初始化:传递进来的配置项替换默认的配置项
options = Object.assign({
title:'系统提⽰',
template:null,
frag:true,
buttons:[{
text:'确定',
click(){
}
}]
},options)
}
命令模式init()执⾏逻辑
创建DOM
//创建DOM结构
creatDom(){
//如果⽤creatElement插⼊DOM,每⼀次动态插⼊,都会导致DOM的回流,⾮常消耗性能,所以最外⾯使⽤createElement创建,内部使⽤字符串的⽅式拼写进去,创建好了之后放到最外层的容器当中,只引起⼀次回流      let frag = ateDocumentFragment()
let dpnDialog = ateElement('div')
dpnDialog.className = 'dpn-dialog'
dpnDialog.innerHTML = `
<div class="dpn-title">
系统温馨提⽰
<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 = ateElement('div')
dpnModel.className = 'dpn-model'
frag.appendChild(dpnModel)
document.body.appendChild(frag)//使⽤frag只需要往页⾯中插⼊⼀次,减少回流次数
frag = null
this.dpnDialog = dpnDialog//挂载到实例上,便于其他⽅法的控制隐藏,并且是私有的实例,
this.dpnModel = dpnModel
}
对参数进⾏处理
creatDom() {
let {title, template, buttons} = this.options
//如果⽤creatElement插⼊DOM,每⼀次动态插⼊,都会导致DOM的回流,⾮常消耗性能,所以最外⾯使⽤createElement创建,内部使⽤字符串的⽅式拼写进去,创建好了之后放到最外层的容器当中,只引起⼀次回流      let frag = ateDocumentFragment()
let dpnDialog = ateElement('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' && deType === 1
template.outerHTML
: template}
</div>
${buttons.length > 0
`<div class="dpn-handle">
${buttons.map((item, index) => {
return `<button index="${index}">${}</button>`
}).join('')}
</div>`
: ''
}
`
frag.appendChild(dpnDialog)
let dpnModel = ateElement('div')
dpnModel.className = 'dpn-model'
frag.appendChild(dpnModel)
document.body.appendChild(frag)//使⽤frag只需要往页⾯中插⼊⼀次,减少回流次数
frag = null
this.dpnDialog = dpnDialog//挂载到实例上,便于其他⽅法的控制隐藏,并且是私有的实例,
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'
}
基于事件委托处理点击事件
init() {
//基于事件委托,实现点击事件的处理
this.dpnDialog.addEventListener('click', (ev)=>{
let target = ev.target,
{tagName,className}= target
console.log([target])
//点击的关闭按钮
if(tagName==='I'&&className.includes('dpn-close')){
this.close()
return
}
//点击的是底部按钮
if(tagName==='BUTTON' && target.parentNode.className.includes('dpn-handle')){          let index = Attribute('index')
//让传过来的函数执⾏,并且函数中的this还必须是当前实例
let func = this.options.buttons[index]['click']
if(typeof func==='function'){
func.call(this)
}
return
}
})
},
基于发布订阅实现回调函数的监听(⽣命周期)
//使⽤:
完整代码
//modalplugin.js
(function () {
//封装插件的时候,需要⽀持很多配置项,有的配置项不传递有默认值,此时我们千万不要⼀个个定义形参,⽤对象的⽅式传形参,好处是可以不穿,⽽且可以不⽤考虑顺序  function ModalPlugin(options) {
return new init(options)
}
//想使⽤创建对象的⽅式创建实例new ModalPlugin()或当做普通函数执⾏也能创建实例ModalPlugin(),需要这样做
ModalPlugin.prototype = {
constructor: ModalPlugin,
//相当于⼤脑,可以控制先⼲什么在⼲什么(命令模式)
init() {
//创建DOM结构
//基于事件委托,实现点击事件的处理
this.dpnDialog.addEventListener('click', (ev) => {