再起航,我的学习笔记之JavaScript设计模式11(外观模式)
经过一段时间的学习与分享,我们对创建型设计模式已经有了一定的认识,未来的一段时间里我们将展开新的篇章,开始迈入结构性设计模式的学习。
结构性设计模式与创建型设计模式不同,结构性设计模式更偏向于关注如何将类和对象组合成更大、更复杂的结构,以简化设计。
外观模式
外观模式(Facede): 为一组复杂的子系统接口提供一个更高级的统一接口,通过这个接口使得对子系统接口的访问更容易。在JavaScript中有时也会用于对底层结构兼容性做统一的封装来简化用户使用。
这个含义看上去有点抽象,下面我将通过示例为大家演示外观模式,但是在了解外观模式之前,我们先讲一下,我们接下来例子中会演示的dom0级事件和dom2级事件
DOM0级事件
DOM0级事件主要是指on+事件类型,比如我们的onclick事件。
其实在W3C标准里是是没有DOM0级的。但是在我们平时阅读的时候可能会读到DOM0级(DOM Level0)的字眼。实际上,DOM0级标准是不存在的,所谓的DOM0级是DOM历史坐标中的一个参照点而已,具体说呢,DOM0级指的是IE4和Netscape 4.0这些浏览器最初支持的DHTML,大概2000年的时候争论过DOM0的问题,最后结论大概是,没有官方形成此标准。
dom0级事件有个特点就是后定义的事件处理会覆盖前面的。我们来看一个示例:
document.getElementById('btn').onclick=function(){
console.log('第一个点击事件');
}
document.getElementById('btn').onclick=function(){
console.log('第二个点击事件');
}
现在我们看看结果,我们发现后面定义的事件果然覆盖了前面的事件。

DOM2级事件
DOM2级事件主要是指addEventListener(events,handler,boolean),removeEventListener(events,handler)这类事件
当然DOM2级事件的特点是不会覆盖自身,而且和DOM0级事件也能共存。我们来看下面的示例。
document.getElementById('btn').addEventListener("click",function(){
console.log("监听第一个点击事件");
})
document.getElementById('btn').addEventListener("click",function(){
console.log("监听第二个点击事件");
})
我们可以看到,我们为btn绑定的两个点击事件均被触发。

此处我们只简单介绍这两个级别的事件其他事件如果有兴趣大家可以自行查阅资料
那么我们现在讲的DOM0级事件和DOM2级事件和外观模式又有什么联系呢?
我们都知道浏览器的兼容是个很麻烦的事情,就比如我们的addEventListener监听事件在老版本的IE浏览器是不支持的,所以那些老版本的浏览器我们要用attachEvent来实现,当然如果碰到了不支持DOM2级事件处理的浏览器,那么我们只能用on事件方法去绑定事件
所以这个时候我们就可以用外观模式去封装他们。
外观模式
如同我们定义里说的一样为一组复杂的子系统接口提供一个更高级的统一接口,我们通过下面这个示例为大家演示外观模式
function addEvent(dom,type,fn){
//对于支持DOM2级事件并且支持监听事件的浏览器我们使用监听事件
if(dom.addEventListener){
dom.addEventListener(type,fn);
}//对于支持DOM2级事件但不支持监听事件的浏览器我们用attachEvent方法
else if(dom.attachEvent){
dom.attachEvent('on'+type,fn);
}//对于不支持DOM2级事件的浏览器,我们只能用on+'事件名'的DOM0级事件方式
else{
dom['on'+type]=fn;
}
}
我们来试一试
var btn=document.getElementById('btn');
addEvent(btn,'click',function(){
console.log("绑定第一个事件")
})
addEvent(btn,'click',function(){
console.log("绑定第二个事件")
})
因为浏览器版本支持监听事件所以我们触发了第一种方法

进一步解决兼容问题
从我们上面的介绍其实我们可以进一步延伸,很多兼容问题我们都可以通过外观模式去解决,比如低版本的IE不兼容preventDefault方法和target属性,那么我们同样可以通过外观模式来解决
var getEvent=function(event){
//标准浏览器返回event,IE返回window.event
return event||window.event;
}
var getTarget=function(event){
var event=getEvent(event);
//标准浏览器返回target,IE返回srcElement
return event.target||event.srcElement;
}
var preventDefault=function(event){
var event=getEvent(event);
//标准浏览器
if(event.preventDefault){
event.preventDefault();
}//IE浏览器
else{
event.returnValue=false;
}
}
我们来试一下
document.onclick=function(e){
//阻止默认行为
preventDefault(e);
//获取事件源目标对象
if(getTarget(e)!==document.getElementById('btn')){
console.log("阻止");
}
}
我们看到只要在我们btn按钮之外的地方点击,这个事件都会输出阻止

总结
通过外观模式,对接口的二次封装隐藏其复杂性,并简化其使用是一种不错的时间,当然这种实践多少都会增加一些资源的开销以及程序的复杂度。不过这种开销对于使用成本来说是可以忽略的。
外观模式是对接口方法的外层包装,以供上层代码调用。因此有时外观模式封装的接口方法不需要接口的具体实现,只需要按照接口使用规则使用即可。这也是对系统与客户之间的一种松散耦合。使得系统与客户之间不会因结构的变化而互相 影响。
也谢谢大家看到这里:)如果你觉得我的分享还可以请点击推荐,分享给你的朋友让我们一起进步~
好了以上就是本次分享的全部内容,本次示例参考自JavaScript设计模式一书,让我们一点点积累一点点成长,希望对大家有所帮助。
欢迎转载,转载请注明作者,原文出处。
再起航,我的学习笔记之JavaScript设计模式11(外观模式)的更多相关文章
- 再起航,我的学习笔记之JavaScript设计模式08(建造者模式)
我的学习笔记是根据我的学习情况来定期更新的,预计2-3天更新一章,主要是给大家分享一下,我所学到的知识,如果有什么错误请在评论中指点出来,我一定虚心接受,那么废话不多说开始我们今天的学习分享吧! 前几 ...
- 再起航,我的学习笔记之JavaScript设计模式09(原型模式)
我的学习笔记是根据我的学习情况来定期更新的,预计2-3天更新一章,主要是给大家分享一下,我所学到的知识,如果有什么错误请在评论中指点出来,我一定虚心接受,那么废话不多说开始我们今天的学习分享吧! 我们 ...
- 再起航,我的学习笔记之JavaScript设计模式14(桥接模式)
桥接模式 桥接模式(Bridge): 在系统沿着多个维度变化的同时,又不增加其复杂度并已达到解耦 从定义上看桥接模式的定义十分难以理解,那么我们来通过示例来演示什么是桥接模式. 现在我们需要做一个导航 ...
- 再起航,我的学习笔记之JavaScript设计模式17(模板方法模式)
模板方法模式 由模板方法模式开始我们正式告别结构型设计模式,开始行为型设计模式的学习分享 行为型设计模式用于不同对象之间职责划分或算法抽象,行为型设计模式不仅仅涉及类和对象,还涉及类或对象之间的交流模 ...
- 再起航,我的学习笔记之JavaScript设计模式20(策略模式)
策略模式 策略模式(Strategy):将定义的一组算法封装起来,使其相互之间可以替换.封装的算法具有一定的独立性,不会随客户端变化而变化. 其实策略模式在我们生活中可应用的地方还是比较多的,比如在商 ...
- 再起航,我的学习笔记之JavaScript设计模式22(访问者模式)
访问者模式 概念介绍 访问者模式(Visitor): 针对于对象结构中的元素,定义在不改变该对象的前提下访问结构中元素的新方法 解决低版本IE兼容性 我们来看下面这段代码,这段代码,我们封装了一个绑定 ...
- 再起航,我的学习笔记之JavaScript设计模式24(备忘录模式)
备忘录模式 概念介绍 备忘录模式(Memento): 在不破坏对象的封装性的前提下,在对象之外捕获并保存该对象内部的状态以便日后对象使用或者对象恢复到以前的某个状态. 简易分页 在一般情况下我们需要做 ...
- 再起航,我的学习笔记之JavaScript设计模式25(迭代器模式)
迭代器模式 概念介绍 迭代器模式(Iterator): 在不暴露对象内部结构的同时,可以顺序地访问聚合对象内部的元素. 迭代器 程序中的循环是一种利器,循环语句也使我们程序开发更简洁高效,但是有时一遍 ...
- 再起航,我的学习笔记之JavaScript设计模式26(解释器模式)
解释器模式 概念介绍 解释器模式(Interpreter):给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子. 获取元素在页面中的路径 我们都知道获取一个 ...
随机推荐
- 谈谈tableView的重要属性内边距
全屏穿透效果需要做到两点 tableView的可视范围占据整个父控件(或者屏幕)--设置contentsize滚动范围. 所有的cell都可以被看到,也就是说tableView中的cell不会被导航栏 ...
- jsp,2016.11.28
1,在jsp中要关联到js的时候就要导入js才可以调用到js <!-- 导入地区的js --> <script type="text/javascript" sr ...
- 狙杀ES6之开光篇
前言 最近有很多小伙伴在后台留言说,闰土哥,是时候来一波干货了!(机智的你们似乎已经猜到我接下来要说什么了,哈哈-).没错,今天闰土为大家带来了久违的干货文章,而且是一个系列的哦!(文章系列较长,请自 ...
- 微信小程序简述
最近在公司实习,经理要求做一个微信小程序,晚上闲时来写一下. 微信小程序问世没多久,但毋庸置疑的是在不久的将来,它可以替代掉很多的APP.个人认为它的优势在于占用资源少,可以做到即用即走,对于一些使用 ...
- [luogu P3128][USACO15DEC]Max Flow [LCA][树上差分]
题目描述 Farmer John has installed a new system of pipes to transport milk between the stalls in his b ...
- ASP.NET底层封装HttpModule实例---FormsAuthentication类的分析
HttpModule是用来注册HttpApplication事件的,实现IHttpModule接口的托管代码模块可以访问该请求管道的所有事件.那么对于我们最常用的ASP.NET Forms身份验证模块 ...
- iOS开发实战-时光记账Demo 网络版
之前写了一个本地数据库版本 戳这里 现在这个就是增加了后台 登录注册页面以及web的上传记录展示页面 含有少量php有兴趣可以看下 另外demo中包括数据库操作.json.网络请求等都没有用到第三方库 ...
- 任务调度---crontab
1. crontab相当于windows下的任务与计划,可以设定定时任务,周期执行的任务 2. 设置任务调度文件 crontab -e 进入任务界面,添加如下命令 0 2 * * ...
- apache2修改用户和组
grep nobody /etc/{passwd,group} groupadd nobody #有nobody用户的情况 usermod -G nobody nobody #没有nobody用户的情 ...
- 白话ASP.NET MVC之一:Url 路由
好久没有写关于ASP.NET MVC的东西了,虽然<ASP.NET MVC4框架揭秘>已经完完整整的看完一遍,但是感觉和一锅粥差不多,没什么可写的,因为我自己不理解,也就写不出来.现在开始 ...