极乐门资源网 Design By www.ioogu.com
基于原生JS封装Modal对话框插件,具体内容如下所示:
原生JS封装Modal对话框插件,个人用来学习原理与思想,只有简单的基本框架的实现,可在此基础上添加更多配置项
API配置
//基本语法 let modal = ModalPlugin({ //提示的标题信息 title:'系统提示', //内容模板 字符串 /模板字符串/DOM元素对象 template:null, //自定义按钮信息 buttons:[{ //按钮文字 text:'确定', click(){ //this:当前实例 } }] }) modal.open()//=>打开 modal.close()//=>关闭 //基于发布订阅,实现回调函数的监听 modal.on('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' && module.exports !== 'undefined') {//如果module不存在,typeof不会出错,会返回undefined module.exports = ModalPlugin;//CommonJS规范,只有在webpack环境下才支持 } })()
使用对象和函数创建实例
想使用创建对象的方式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' && module.exports !== 'undefined') {//如果module不存在,typeof不会出错,会返回undefined module.exports = ModalPlugin;//CommonJS规范,只有在webpack环境下才支持 } })()
配置项
//封装插件的时候,需要支持很多配置项,有的配置项不传递有默认值,此时我们千万不要一个个定义形参,用对象的方式传形参,好处是可以不传,而且可以不用考虑顺序 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 = document.createDocumentFragment() let dpnDialog = document.createElement('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 = document.createElement('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 = 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 "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只需要往页面中插入一次,减少回流次数 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.creatDom() //基于事件委托,实现点击事件的处理 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 = target.getAttribute('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.creatDom() //基于事件委托,实现点击事件的处理 this.dpnDialog.addEventListener('click', (ev) => { let target = ev.target, {tagName, className} = target //点击的关闭按钮 if (tagName === 'I' && className.includes('dpn-close')) { this.close() return } //点击的是底部按钮 if (tagName === 'BUTTON' && target.parentNode.className.includes('dpn-handle')) { let index = target.getAttribute('index') //让传过来的函数执行,并且函数中的this还必须是当前实例 let func = this.options.buttons[index]['click'] if (typeof func === 'function') { func.call(this) } return } }) this.fire('init')//通知init方法执行成功 }, //创建DOM结构 creatDom() { let {title, template, buttons} = this.options //如果用creatElement插入DOM,每一次动态插入,都会导致DOM的回流,非常消耗性能,所以最外面使用createElement创建,内部使用字符串的方式拼写进去,创建好了之后放到最外层的容器当中,只引起一次回流 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 "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只需要往页面中插入一次,减少回流次数 frag = null this.dpnDialog = dpnDialog//挂载到实例上,便于其他方法的控制隐藏,并且是私有的实例, this.dpnModel = dpnModel }, //控制他显示 open() { this.dpnDialog.style.display = 'block' this.dpnModel.style.display = 'block' this.fire('open')//通知open方法执行成功 }, //控制隐藏 close() { this.dpnDialog.style.display = 'none' this.dpnModel.style.display = 'none' this.fire('close')//通知close方法执行成功 }, //on向事件池中订阅方法 on(type, func) { let arr = this.pond[type] if(arr.includes(func)) return arr.push(func) }, //通知事件池中的方法执行 fire(type) { let arr = this.pond[type] arr.forEach(item => { if(typeof item ==='function'){ item.call(this) } }) } } function init(options) { //接下来将所有的操作全部写在init里面 //参数初始化:传递进来的配置项替换默认的配置项 options = Object.assign({ title: '系统提示', template: null, frag: true, buttons: [{}] }, options) //把信息挂载到实例上: 在原型的各个方法中,只要this是实例,都可以调用到这些信息 this.options = options; this.pond = { init: [], close: [], open: [] } this.init() } init.prototype = ModalPlugin.prototype; // 浏览器直接导入,这样的方法是暴露到全局的 window.ModalPlugin = ModalPlugin; //如果还需要支持ES6Module/CommonJS模块导入规范,在react项目当中,vue项目当中也想用 if (typeof module !== 'undefined' && module.exports !== 'undefined') {//如果module不存在,typeof不会出错,会返回undefined module.exports = ModalPlugin;//CommonJS规范,只有在webpack环境下才支持 } })()
使用
使用时需要引入modalpugin.js
和modalpugin.css
使用示例1:
//使用: const modal1 = ModalPlugin({ //提示的标题信息 title: '系统提示', //内容模板 字符串 /模板字符串/DOM元素对象 template: null, //自定义按钮信息 buttons: [{ //按钮文字 text: '确定', click() { //this:当前实例 this.close() } }, { //按钮文字 text: '取消', click() { //this:当前实例 this.close() }, }] }) modal1.on('open',()=>{ console.log('我被打开了1') }) modal1.on('open',()=>{ console.log('我被打开了2') }) modal1.on('close',()=>{ console.log('我被关闭了') }) modal1.open()
使用示例2:
github
完整代码github
极乐门资源网 Design By www.ioogu.com
极乐门资源网
免责声明:本站文章均来自网站采集或用户投稿,网站不提供任何软件下载或自行开发的软件!
如有用户或公司发现本站内容信息存在侵权行为,请邮件告知! 858582#qq.com
极乐门资源网 Design By www.ioogu.com
暂无基于原生JS封装的Modal对话框插件的示例代码的评论...
RTX 5090要首发 性能要翻倍!三星展示GDDR7显存
三星在GTC上展示了专为下一代游戏GPU设计的GDDR7内存。
首次推出的GDDR7内存模块密度为16GB,每个模块容量为2GB。其速度预设为32 Gbps(PAM3),但也可以降至28 Gbps,以提高产量和初始阶段的整体性能和成本效益。
据三星表示,GDDR7内存的能效将提高20%,同时工作电压仅为1.1V,低于标准的1.2V。通过采用更新的封装材料和优化的电路设计,使得在高速运行时的发热量降低,GDDR7的热阻比GDDR6降低了70%。
更新日志
2024年11月16日
2024年11月16日
- 齐豫.2003-THE.UNHEARD.OF.CHYI.3CD【苏活音乐】【WAV+CUE】
- 黄乙玲1986-讲什么山盟海誓[日本东芝版][WAV+CUE]
- 曾庆瑜1991-柔情陷阱[台湾派森东芝版][WAV+CUE]
- 陈建江《享受男声》DTS-ES6.1【WAV】
- 群星《闪光的夏天 第5期》[FLAC/分轨][392.38MB]
- 徐小凤《三洋母带》1:1母盘直刻[WAV+CUE][981M]
- 王菲1995《菲靡靡之音》[香港首版][WAV+CUE][1G]
- 《双城之战》主题小游戏现已上线 扮演金克丝探索秘密基地
- 《霍格沃茨之遗》PS5Pro画面对比:光追性能显著提升
- 《怪猎荒野》PS5Pro主机版对比:B测性能都不稳定
- 黄宝欣.1992-黄宝欣金装精选2CD【HOMERUN】【WAV+CUE】
- 群星.1996-宝丽金流行爆弹精丫宝丽金】【WAV+CUE】
- 杜德伟.2005-独领风骚新歌精选辑3CD【滚石】【WAV+CUE】
- 安与骑兵《心无疆界》[低速原抓WAV+CUE]
- 柏菲唱片-群星〈胭花四乐〉2CD[原抓WAV+CUE]