- HTML部分只有两个按钮,用于唤起dialog弹窗
<!--
按钮1打开的是不带input的弹窗
按钮2打开的是在按钮1调用基础上继承的类并带input框的弹窗
-->
<button class="dailog1">点击</button>
<button class="dailog2">点击2</button>
- js部分涉及到ES6相关的部分包括,class语法,ES5版本的继承,ES6相关的继承,事件委托,自定义事件
// 对内:封闭;对外:开放(api、配置)
/*
这部分的参数也就是目前组件支持的参数
{
width: "30%",
height: "250px",
title: "测试标题",
content: "测试内容",
dragable: true, //是否可拖拽
maskable: true, //是否有遮罩
isCancel:false //是否有取消
}
*/
/*
* 构造函数
* 1. 约定俗成:首字母大写
* 2. 属性放到构造函数,方法放在原型里面
* 方法之所以放原型是因为可以实现公共空间,节省内存
*/
class MyDialog extends EventTarget {
constructor (options) {
super()
this.opts = Object.assign({
width: "30%",
height: "250px",
title: "测试标题",
content: "测试内容",
dragable: true, //是否可拖拽
maskable: true, //是否有遮罩
isCancel:false, //是否有取消
success: () => {
console.log('点击了默认确认');
},
close: () => {
console.log('点击了默认关闭');
}
}, options)
this.init()
}
// 组件初始化时调用的方法
init() {
this.renderShow()
// 自定义事件,通过自定义事件实现事件监听
let close = new Event('close')
this.addEventListener('success', this.opts.success)
this.addEventListener('cancel', this.opts.cancel)
// 1. 采用这种方式进行按钮的处理,会出现按钮不存在的时候报错的问题,所以使用事件委托的机制,也就是备注1.1涉及到的代码
// this.dialogHtml.querySelector('.k-close').onclick = () => {
// this.close()
// }
// this.dialogHtml.querySelector('.k-cancel').onclick = () => {
// this.close()
// }
// this.dialogHtml.querySelector('.k-primary').onclick = () => {
// this.close()
// }
// 1.1 使用事件委托实现
// 事件委托:子节点个数不固定,或者说子节点是动态渲染,不一定会存在时,如果想要给某个时间加节点事件,是无法直接获取到节点的,这时候可以通过获取到父节点,通过事件的e.target获取到当前点击的节点
// 在此处的应用实例是取消按钮是可以动态控制展示与否的,如果不进行事件委托,直接绑定事件会导致页面报错
this.dialogHtml.onclick = e => {
switch(e.target.className) {
case 'k-close':
this.close();
// 事件注入
this.dispatchEvent(close)
// this.opts.close()
break
case 'k-cancel':
this.close();
this.dispatchEvent(close)
// this.opts.close()
break
case 'k-primary':
this.close();
this.comfirm()
// this.opts.success()
break
}
}
}
// 点击确认时,调用的方法
comfirm(value) {
let success = new CustomEvent('success', {
detail: value
})
this.dispatchEvent(success)
}
// 点击页面按钮时,调用这个方法
show() {
if(this.opts.maskable) {
this.dialogHtml.querySelector('.k-wrapper').style.display = 'block'
}
this.dialogHtml.querySelector('.k-dialog').style.display = 'block'
}
// 点击取消获取关闭时调用页面的这个方法
close() {
this.dialogHtml.querySelector('.k-wrapper').style.display = 'none'
this.dialogHtml.querySelector('.k-dialog').style.display = 'none'
}
// 页面通过Js动态渲染
renderShow() {
this.dialogHtml = document.createElement('div')
this.dialogHtml.innerHTML = `
<div class="k-wrapper"></div>
<div class="k-dialog" style="width: ${this.opts.width}; height: ${this.opts.height}">
<div class="k-header">
<span class="k-title">${this.opts.title}</span><span class="k-close">X</span>
</div>
<div class="k-body">
<span>${this.opts.content}</span>
</div>
<div class="k-footer">
${this.opts.isCancel ? '<span class="k-cancel">取消</span>' : ''}
<span class="k-primary">确定</span>
</div>
</div>
`
document.body.append(this.dialogHtml)
}
}
// 通过类的继承,在原有的MyDialog增加或者修改方法
class inputDialog extends MyDialog {
constructor(options) {
// 继承的时候一定要调用super,传参也是通过super进行传递
super(options)
this.inputRender()
}
// 在原有的MyDialog基础上插入一个input框
inputRender() {
let input = document.createElement('input')
input.className = 'input-inner'
input.type = 'text'
this.dialogHtml.querySelector('.k-body').append(input)
}
// 点击确认时,可以获取到输入框的内容
comfirm() {
const value = this.dialogHtml.querySelector('.input-inner').value
// super.comfirm方法可以实现修改原方法的基础上继承原方法
super.comfirm(value)
}
}
let dialog1 = new MyDialog({
width: '300px',
height: '250px',
isCancel: true,
success() {
console.log('点击了确认');
},
close() {
console.log('点击了关闭');
}
})
document.querySelector('.dailog1').onclick = function() {
dialog1.show()
}
// new 进行实例化对象
/*
* new 运算符有如下几个作用
* 1. 执行函数
* 2. 自动创建一个空对象
* 3. 把创建的对象指向另一个对象,也就是调用的对象
* 4. 把空对象和函数里的this衔接起来
* 5. 隐式返还this
*/
let dialog2 = new inputDialog({
width: '300px',
height: '250px',
isCancel: true,
success(e) {
console.log('点击了确认', e.detail);
},
close() {
console.log('点击了关闭');
}
})
document.querySelector('.dailog2').onclick = function() {
dialog2.show()
}