再起航,我的学习笔记之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):给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子. 获取元素在页面中的路径 我们都知道获取一个 ...
随机推荐
- vue.js 生命周期
boforeCreate 创建之前 created 创建之后 boforeMount 实例化之前 mounted 实例化之后 话不多说,直接上代码 & ...
- Chrome浏览器扩展开发系列之十六:扩展中可用的Chrome浏览器API
除了Chrome浏览器支持的chrome.* API之外,Chrome浏览器扩展还可以使用Chrome浏览器为Web页面或Chrome app提供的APIs.对于Chrome浏览器2支持的API,还可 ...
- Chrome浏览器扩展开发系列之十一:NPAPI插件的使用
在Chrome浏览器扩展中使用HTML和JavaScript非常容易,但是如何重用已有的非JavaScript遗留系统代码呢?答案是将NPAPI插件绑定到Chrome浏览器扩展,从而实现在Chrome ...
- 三、使用vscode在docker中debug
上篇博文中分享了如何用docker-compose搭建AspNetCore的开发环境,在开发过程中debug是必不可少的,如果你使用VS2017的话,右键就可以了,而作为跨平台的.net core开发 ...
- JavaScript中闭包实现的私有属性的getter()和setter()方法
注意: 以下的输出都在浏览器的控制台中 <!DOCTYPE html> <html> <head> <meta charset="utf-8&quo ...
- [Oracle]约束(constraint)
(一)约束的概念 在Oracle中,可以通过设置约束来防止无效数据进入表中.Oracle一共有5种约束: 主键约束(primary key) 外键约束(foreign key) 唯一性约束(uniqu ...
- Spring定时器实现(一)
Spring定时器简单应用实现,如下: 首先.Spring配置文件: <?xml version="1.0" encoding="UTF-8"?> ...
- tensorflow Relu激活函数
1.Relu激活函数 Relu激活函数(The Rectified Linear Unit)表达式为:f(x)=max(0,x). 2.tensorflow实现 #!/usr/bin/env pyth ...
- 【LeetCode题解】动态规划:从新手到专家(一)
文章标题借用了Hawstein的译文<动态规划:从新手到专家>. 1. 概述 动态规划( Dynamic Programming, DP)是最优化问题的一种解决方法,本质上状态空间的状态转 ...
- Angular页面加载后自动弹窗
首先在控制器内写好一个弹窗,我用的是ionic的默认提示对话框 // 一个确认对话框 $scope.showConfirm = function() { var confirmPopup = $ion ...