外观模式(Faceade):为一组复杂的子系统接口提供一个更高级的统一接口,通过这个接口使得对子系统接口的访问更容易。
在 JavaScript 中有时也会用于对底层结构兼容性做统一封装来简化用户使用。
一,添加一个点击事件
为页面文档 document 对象绑定一个 click 事件来实现隐藏提示框的交互功能。
document.onclick = function(e) {
e.preventDefault();
if (e.target !== document.getElementById('myinput')) {
hidePageAlert();
}
}
function hidePageAlert() {
// 隐藏提示框
}
“首先,你为 document 绑定了 onclick 事件,但是 onclick 是 DOM 0 级事件,相当于为元素绑定一个事件方法。所以我们团队有人再次使用 document 绑定 click 事件时,会将你定义的方法覆盖掉。”
“所以,你应该用 DOM 2 级事件 addEventListener 来实现。但老版本的 IE 浏览器(低于 IE9 )不支持这个方法,要用 attachEvent。当然如果有不支持 DOM 2 级事件的浏览器,只能用 onclick。”
二,兼容方式
在 JavaScript 中可以通过一个”套餐“来简化复杂的需求,比如我们同一功能接口方法的不统一,我们可以通过外观模式来定义一个统一的接口方法。
这样就提供了一个更简单的高级接口。
// 使用外观模式封装事件绑定
function addEvent(dom, type, fn) {
if (dom.addEventListener) {
dom.addEventListener(type, fn, false);
} else if (dom.attachEvent) {
dom.attachEvent('on' + type, fn);
} else {
dom['on' + type] = fn;
}
}
// 使用
var myinput = document.getElementById('myinput');
addEvent(myinput, 'click', function() {
console.log('绑定事件');w
})
三,除此之外
外观模式可以简化底层接口复杂性,也可以解决浏览器兼容性问题。
另外两处问题是,在 IE 低版本浏览器中不兼容 e.preventDefault() 和 e.target。
// 获取事件对象
var getEvent = function(event) {
// 标准浏览器返回 event,IE 下 window.event
return event || window.event;
}
// 获取元素
var getTarget = function(event) {
var event = getEvent(event);
// 标准浏览器下 event.target,IE 下 event.srcElement
return event.target || event.srcElement;
}
// 阻止默认行为
var preventDefault = function(event) {
var event = getEvent(event);
// 标准浏览器
if (event.preventDefault) {
event.preventDefault()
} else {
event.returnValue = false;
}
}
之前代码,处理如下:
document.onclick = function(e) {
preventDefault(e)
if (getTarget(e) !== document.getElementById('myinput')) {
hidePageAlert();
}
}
function hidePageAlert() {
// 隐藏提示框
}