用js实现模态弹框
要求:
1.使用构造函数方式实现;
2.使用单例模式,并且多个实例间互不影响,相互独立;
3.弹框标题和内容采用传参的方式获得;
4.存在show()、close()、on()、off()方法,并可链式调用;
5.on方法绑定可事件,并成功调用回调函数;
6.off方法取消事件绑定,并成功调用回调函数;
这是一道机试题,感觉考得挺全面的,原型、架构、事件机制等等,当时状态比较差,没做好,只好回来撸一遍,需要改善的地方还有很多,有空再优化一下。
function Dialog(options) {
if (!(this instanceof Dialog)) return new Dialog(options);
this.options = this.extend(this.options, options);
this.init();
}
Dialog.prototype = {
constructor: Dialog,
init: function() {
this.el = document.getElementById(this.options.el)
this.switchs = this.options.switchs
this.type = this.options.type
this.data = this.options.data
this.matchTypes()
},
extend: function(obj, obj2) {
for(var k in obj2) {
obj[k] = obj2[k];
}
return obj;
},
changeSwitchs: function(bool) {
this.switchs = !!bool
this.renders()
},
eventHandels(element, type, fn) {
var element = element instanceof Object ? element : document
if(this.switchs) {
element.addEventListener(type, fn)
element.dispatchEvent(new Event(type))
} else {
fn()
element.removeEventListener(type, fn)
}
this.renders()
},
show: function() {
this.changeSwitchs(true)
return this
},
close: function() {
this.changeSwitchs(false)
return this
},
on: function(element, type, fn) {
this.changeSwitchs(true)
this.eventHandels(element, type, fn)
return this
},
off: function(element, type, fn) {
this.changeSwitchs(false)
this.eventHandels(element, type, fn)
return this
},
onIsOk: function() {
alert('click ok')
},
matchTypes: function(){
var title = this.data.title
var body = this.data.content
switch(this.type) {
case 'maskLog':
this.maskLog()
break
default:
this.logs(title, body)
}
},
logs: function(title, body) {
var warp = document.createElement('div');
warp.innerHTML += "<div>"+ title +"</div>\
<div>"+ body +"</div>\
<button id='isOk'>确定</button>\
<button id='isCancel'>取消</button>";
this.el.appendChild(warp);
var isOk = document.getElementById('isOk')
var isCancel = document.getElementById('isCancel')
var self = this
var _list = [isOk, isCancel]
_list.forEach(function(item){
item.addEventListener('click', function(){
if(this.id === 'isOk') self.onIsOk()
self.close()
},false)
})
},
renders: function() {
if(this.switchs) {
this.el.style.visibility = 'visible'
} else {
this.el.style.visibility = 'hidden'
}
},
options: {
title: 'title',
context: 'context',
theme: '',
type: 'normal',
switchs: false,
}
}