欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

JS设计模式——结构设计

程序员文章站 2024-03-24 20:21:28
...

结构型设计模式

结构型设计模式关注如何将类或对象组合成更大更复杂的结结构,以简化设计

一、外观模式

外观模式: 为一组复杂的子系统接口提供一个更高级的统一接口,通过这个接口使得对子系统的结果更容易访问
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.targete.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'
})