学习书籍:《JavaScript设计模式》
学习目标:
- 外观模式、适配器模式、装饰者模式
学习内容:
为一组复杂的子系统接口提供一个更高级的统一接口,通过这个接口使得对子系统接口访问更容易。
/* 使用外观模式定义一个统一的接口方法,简化对复杂底层接口不统一的使用需求 */
// 外观模式的实现(一)
function addEvent(dom, type, fn){
if (dom.addEventListener){
// 对于支持DOM2级事件处理程序addEventListener方法游览器
dom.addEventListener(type, fn, false);
}else if (dom.attachEvent) {
// 对于不支持addEventListener方法但支持attachEvent方法的游览器
dom.attachEvent('on' + type, fn);
}else{
// 对于不支持addEventListener方法也不支持attachEvent方法, 但支持on+'事件名'的游览器
dom['on' + type] = fn;
}
}
// 外观模式的实现(二)
// 获取时间对象
var getEvent = fuinction(event){
// 标准游览器返回event, IE下window.event
return event || window.event
}
// 获取元素
var getTarget = fuinction(event){
var event = getEvent(event);
// 标准游览器返回event.target, IE下event.srcElement
return event.target || event.srcElement
}
// 外观模式的实现(三)
// 简约版属性样式库
var A = {
g: function(id){
return document.getElementById(id);
},
css: function(id, key, value){
return document.getElementById(id).style[key] = value;
// return document.getElementById(id)[key] = value;
}
}
适配器模式:将一个类(对象)的接口(方法或者属性)转换为另外一个接口,以满足用户要求,使类(对象)之间接口不兼容问题通过适配器得以解决。
/* 适配异类框架 */
// 定义一个框架
var A = A || {}
// 通过ID获取元素
A.g = function(id) {
return document.getElementById(id)
}
// 为元素绑定事件
A.on = function(id, type, fn){
// 如果传递参数是字符串则以id处理,否则以元素对象处理
var dom = typeof id === 'string' ? this.g(id): id;
if (dom.addEventListener){
// 标准DOM2级添加事件方式
dom.addEventListener(type, fn, false);
}else if(dom.attachEvent){
// ie DOM2级添加事件方式
dom.attachEvent('on' + type, fn)
}else{
dom['on' + type] = fn;
}
}
// 窗口加载完成事件
A.on(window, 'load', function(){
// 按钮点击事件
A.on('mybutton', 'click', function(){
// do something
})
})
// 引入jQuery替换原有的库
A.g = function(id){
// 通过jQuery获取jQuery对象,然后返回第一个成员
return $(id).get(0);
}
A.on = function(id, type, fn){
// 如果传递参数是字符串则以id处理,否则以元素对象处理
var dom = typeof id === 'string' ? $('#' + id): $(id);
dom.on(type, fn)
}
/* 参数适配器 */
function doSomeThing(obj){
var _obj = {
name: "书籍",
title: "设计",
age: 2,
size: 10
};
for (var i in _obj){
_obj[i] = obj[i] || _obj[i];
}
}
/* 数据适配 */
function arrObj(arr){
return {
name: arr[0],
type: arr[1],
title: arr[2]
}
}
装饰者模式:在不改变原对象的基础上,通过对其进行包装拓展(添加属性或者方法)使原有对象可以满足用户的更复杂需求。
// 装饰器
var decorator = function(input, fn){
// 获取事件源
var input = document.getElementById(input);
if (typeof input.onclick === 'function'){
// 缓存事件源原有回调函数
var oldClickFn = input.onclick;
// 为事件源定义新的事件
input.onclick = function(){
// 事件源原有回调函数
oldClickFn();
// 执行事件源新增回调函数
fn();
}
}else{
// 事件源未绑定事件,直接为事件源添加新增回调函数
input.onclick = fn;
}
}
// 姓名输入框功能装饰
decorator('name_input', function(){
document.getElementById('name_demo_text').style.display = 'none';
})