使用规范
正常封装一个组件要从组件的使用说起,当调用message(options)时就会在页面中显示一个
实现步骤分析
一般都会把实现放到一个闭包内,window.xxx,把全局要用到的方法暴漏到window中,每个方法中new 一个Dialog实例并传入options,一般组件的封装就要定义一个类每一个组件都是一个实例有自己的私有属性,又有公有属性,还可以在共有方法中使用私有属性,所以最核心的就是如何书写Dialog类
代码
let mesBut = document.querySelector(".messageBut")
let diaBut = document.querySelector(".dialogBut");
(function() {
let mesBut = document.querySelector(".messageBut")
let diaBut = document.querySelector(".dialogBut");
(function() {
class Dialog {
constructor(options = {}) {
//如果显示dialog,template传入的内容是字符串就要把他转成dom节点
//方便对template的统一操作
let tem = options.template
if (tem && typeof tem === "string") {
let frag = document.createElement("div")
frag.innerHTML = tem
options.template = frag
}
//把options挂载在实例上
this.options = options
//对于全局要使用的添加到实例上
this._myMessage = null
this._diaBox = null
//初始化
this.init()
options.oninit.call(this, this)
}
init() {
//先创建相应的页面结构放入body中,之后为元素绑定事件
let {
status
} = this.options
if (status === "message") {
this.create()
this.bindEvent()
this.open()
} else {
this.create()
this.bindEvent()
this.open()
}
}
create() {
let {
status,
type,
message,
title,
click,
template,
} = this.options
if (status === "message") {
let fragment = document.createElement("div")
fragment.innerHTML = `<div class="message-box message-${type}">
<span>${message}</span>
<i>x</i>
</div>`
//存储dom到当前对象方便之后使用
this._myMessage = fragment
document.body.appendChild(fragment)
} else {
let mask = document.querySelector(".mask")
let oldbox = document.querySelector(".dialog-box")
let box = oldbox
if (!box) {
box = document.createElement("div")
box.className = "dialog-box"
}
this._diaBox = box
box.innerHTML = `<div class="dialog-header">
<h3>${title}</h3>
<i>x</i></div>
<div class="dialog-content"></div>
${click&&click.length>0?`<div class="dialog-footer">
${click.map(item=>{
return `<button text=${item.text}>${item.text}</button>`
}).join("")}</div>`:""}`
if (!mask) {
mask = document.createElement("div")
mask.className = "mask"
document.body.appendChild(mask)
}
this._mask = mask
oldbox?null:document.body.appendChild(box)
this._diaBox.querySelector(".dialog-content").appendChild(template)
}
}
bindEvent(){
let {
status,
click
} = this.options
if (status === "message") {
let beyI=this._myMessage.querySelector("i")
beyI.addEventListener("click",(ev)=>{
this.close()
})
} else {
this._diaBox.addEventListener("click",(ev)=>{
//获取dialog点击的元素
let target=ev.target
//得到点击元素的标签名
let tagName=target.tagName
//如果是i直接关闭
if(tagName==="I"&&target.parentNode.className==="dialog-header"){
this.close()
//如果点击的是按钮,要知道是按钮的text
}else if(tagName==="BUTTON"&&target.parentNode.className==="dialog-footer"){
let text=target.getAttribute("text")
let now=click.find(item=>{
return item.text===text
})
now.func.call(this,this)
this.close()
}
})
}
}
open(){
let {
status,
onopen
} = this.options
if (status === "message") {
this.moveMessage()
onopen.call(this,this)
} else {
this._diaBox.style.display="block"
this._mask.style.display="block"
this._diaBox.offsetTop
this._diaBox.style.opacity=1
this._mask.style.opacity=1
onopen.call(this,this)
}
}
moveMessage(){
let messages=document.querySelectorAll(".message-box")
messages=[].slice.call(messages)
messages[0]&&messages[0].offsetTop
messages.forEach((item,index)=>{
item.style.top=index===0?"20px":20+50*index+"px"
})
}
close(){
let {
status,
onclose
} = this.options
if (status === "message") {
let messageBox=this._myMessage.querySelector(".message-box")
messageBox.style.top="-200px"
messageBox.ontransitionend=()=>{
messageBox.ontransitionend=null
document.body.removeChild(this._myMessage)
this.moveMessage()
onclose.call(this,this)
}
} else {
this._diaBox.style.opacity=0
this._mask.style.opacity=0
this._diaBox.offsetTop
this._diaBox.style.display="display"
this._mask.style.display="display"
onclose.call(this,this)
}
}
}
window.useMessage = function useMessage(options = {}) {
new Dialog(options)
}
window.useDialog = function useDialog(options = {}) {
new Dialog(options)
}
})()
mesBut.addEventListener("click", () => useMessage({
status: "message",
message: "信息正确",
type: "info",
oninit() {},
onopen() {},
onclose() {},
}))
diaBut.addEventListener("click", () => useDialog({
status: "dialog",
title: "题目",
template: "hahah",
click: [{
text: "确定",
func() {}
}, {
text: "取消",
func() {}
}],
oninit() {},
onopen() {},
onclose() {},
}))