结构型设计模式:将类或对象组合,简化设计
外观模式概念:为一组复杂的子系统接口提供一个更高级的统一接口。
简而言之: 统一接口,方便调用(套餐服务)
应用: 兼容方法封装,简化底层操作
1.1 简化底层接口案例 --- 点击事件
情景说明: 在一个dom元素上绑定多个onClick事件, 后者会覆盖前者,只执行后面的事件,这是该怎么办?
简单的解决方案:
addEventListener
这个方法绑定多个click 事件都会顺序执行不会被覆盖(像队列一样,先绑定的先执行)
<!--实例代码-->
<div id="app">
<button id="btn">点击</button>
</div>
//IE 8 测试 不能使用let
var btn = document.getElementById('btn')
var fn1 = function() {
alert('fn1')
}
var fn2 = function() {
alert('fn2')
}
btn.addEventListener('click', fn1)
btn.addEventListener('click', fn2)
但是这个方法存在兼容性问题,低于IE9是不支持这个方法的。所以此处显示出外观模式的作用,利用该模式设计统一调用的接口,简化因为兼容性原因接口不统一的问题 --- 简化底层接口复杂性
利用观察模式封装绑定方法接口
<div id="app">
<button id="btn">点击</button>
</div>
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 btn = document.getElementById('btn');
var fn1 = function() {
alert('fn1');
};
var fn2 = function() {
alert('fn2');
};
addEvent(btn, 'click', fn1);
addEvent(btn, 'click', fn2);
tip 需要了解一下DOM0,DOM2
1.2 简化底层接口案例 --- 通过外观模式封装多个功能
<div id="app">
</div>
<script>
var A = {
getDom: function(id) {
return document.getElementById(id)
},
setStyle: function(dom, key, value) {
dom.style[key] = value
},
// getStyle: function(dom, key) {
// return dom.style[key]
// },
setAttr: function(dom, key, value) {
dom.setAttribute(key, value)
},
setText: function(dom, text) {
dom.innerText = text
}
}
//test
var app = A.getDom('app')
A.setText(app, '你好')
A.setAttr(app, 'data-id', 'uuid')
A.setStyle(app, 'background', 'yellow')
</script>
1.3 兼容性案例
目的: 实现阻止默认事件,需要兼容到IE8
//在div 中阻止 a链接默认跳转行为
<div id="app">
<a href="https://www.baidu.com" id="link">百度</a>
</div>
var getEvent = function(e) {
// 标准浏览器 event IE window.event
return e || window.event
}
var getTarget = function(e) {
// console.log(e)
// 标准浏览器 e.target IE e.srcElement
return e.target || e.srcElement
}
// 阻止默认行为
var preventDefault = function(e) {
var event = getEvent(e);
if (event.preventDefault) {
event.preventDefault();
} else {
// IE
event.returnValue = false;
}
}
var div = document.getElementById('app');
var targetDom = document.getElementById('link');
document.onclick = function(e) {
preventDefault(e);
if (getTarget(e) === targetDom) {
alert('preventDefault');
}
}
实践 封装一个获取CSS样式的方法
<div id="app">
</div>
<script>
var getStyle = function(id, key) {
return document.getElementById(id).style[key];
}
console.log(getStyle('app', 'backgroundColor'));
var getCss = function(dom, attr) {
if (dom.currentStyle) {
// IE
return dom.currentStyle[attr];
} else {
return window.getComputedStyle(dom, false)[attr];
}
}
var dom = document.getElementById('app');
console.log(getCss(dom, 'background-color'));
</script>