JS设计模式系列2
- 结构型设计模式
- 一、外观模式
- 1.1. 引言:添加一个点击事件
- 1.2 兼容方式
- 二、适配器模式
- 2.1 适配异类框架
- 2.2参数适配器
- 装饰者模式【神了】
结构型设计模式
结构型设计模式关注如何将类或对象组合成更大更复杂的结结构,以简化设计
一、外观模式
外观模式: 为一组复杂的子系统接口提供一个更高级的统一接口,通过这个接口使得对子系统的结果更容易访问
emm,这里我第一个想到的就是前端对axios的封装,以及把某个角色或某个功能的api接口单独写在一个js文件里,调用时直接引用文件即可。
1.1. 引言:添加一个点击事件
代码示例
document.onclick = function (e) {
e.preventDefault()
if (e.target !== document.getElementById('myinput')){
hidePageAlert()
}
}
function hidePageAlert(){}
问题1:
onclick
是DOM0级元素,当其他人再为document绑定方法时,会覆盖原先的方法。
问题2: 针对,问题1,应该采用DOM2级事件处理程序提供的方法addEventListener
实现。但这里需要考虑浏览器兼容的问题
问题3:e.preventDefault()和e.target()
也需要考虑兼容的问题
1.2 兼容方式
事件处理
// 外观模式实现事件处理
function addEvent(dom,type,fn) {
// 对于支持DOM2级事件处理程序addEventListener方法的浏览器
if (dom.addEventListener){
dom.addEventListener(type,fn,false)
}
// 对于支持attachEvents的浏览器
else if (dom.attachEvents){
dom.attachEvents('on' + type,fn)
}
// 对于不支持addEvent... 和 attach...,但支持on+'事件名'
else {
dom['on'+type]=fn
}
}
e.target
和e.preventDefault
等
//获取事件对象
var getEvent = function (event){
// IE下是window.event
return event || window.event
}
// 获取元素
var getTarget = function (event) {
var event = getEvent(event)
return event.target || event.srcElement
}
var preventDefault = function (event) {
var event = getEvent(event)
if (event.preventDefault()) {
event.preventDefault()
} else{
event.returnValue = false
}
}
二、适配器模式
适配器模式: 将一个类(对象)的接口转换成另一个接口,使类之间接口的不兼容问题通过适配器得以解决
2.1 适配异类框架
A框架代码
var A = A || {}
a.g = function (id) {
return document.getElementById(id)
}
A.on = function (id,type,fn){
var dom = typeof id === 'string' ? this.g(id) : id
if (dom.addEventListener) {
dom.addEventListener(type, fn, false)
}
else if (dom.attachEvents) {
dom.attachEvents('on' + type, fn)
}
else {
dom['on' + type] = fn
}
}
适配jquery
A.g = function (id) {
return $(id).get(0)
}
A.on = function (id, type, fn) {
var dom = typeof id === 'string' ? $('#' + id) : $id
dom.on(type,fn)
}
2.2参数适配器
用途1: 若方法需要传递多个参数,可以以一个参数对象方式传入
用途2: 调用时不知传递的参数是否完整,此时可以用适配器来适配传入的对象
// 适配传入的对象
function doSomeThing(obj) {
var _adapter = {
name:'wjyGrit',
title:'设计模式',
age:19,
color:'blue',
size:100,
prize:50
}
for (var i in _adapter){
_adapter[i] = obj[i] || _adapter[i]
}
// do things
}
装饰者模式【神了】
装饰者模式 在不改变原对象的基础上,通过对其进行包装扩展,使原有对象可以满足用于的更复杂需求
需求:给用户信息输入框增加一些需求,需要改多个,而且还是不改变原有功能,如果一个一个改又不太好
代码展示
这样,无论输入框是否绑定过输入事件,都可以轻松完成需求,后期再更改也方便
var decorator = function (input, fn) {
var input = document.getElementById(input) //获取事件源
// 若事件源已经绑定事件[还可以这样!!!]
if (typeof input.onclick === 'function') {
// 缓存事件源原有的回调函数
var oldClickFn = input.onclick
// 为事件源定义新的事件
input.onclick = function () {
// 事件源原有回调函数
oldClickFn()
fn(0)
}
} else {
// 事件源未绑定事件,直接为事件源添加新增回调函数
input.onclick = fn
}
//others
}
decorator('tel_input',function () {
document.getElementById('tel_demo_text').style.display = 'none'
})