前端JavaScript设计模式-代理模式实现

代理模式

定义:为一个对象提供一种代理以控制对这个对象的访问

代理对象起到类似中介的作用,会增加一些功能(如,校验,合并等等),也会去掉一些原有对象的功能

虚拟代理-图片加载,文件上传
保护代理-登录操作后才能看全功能,前端校验
远程代理-监控多个对象的状态,总机监控分店
智能代理-提供额外的其他服务, 火车站代售处

举栗

代理模式都少不了送花,这里也不例外

//女神根据心情好坏看是否接受小明的送花
		const Ming = {
			flower: 'sunFlower',
			sendFlowers: function (target) {
				target.acceptFlowers(this.flower);
			}
		}

		//代理人
		const person = {
			proxyFlower: function (target) {
				this.proxySendFlower(target, function () {
					Ming.sendFlowers(target);
				})
			},
			proxySendFlower: function (target, func) {
				this.timer = setInterval(() => {
					if (target.mood) {
						func();
						clearInterval(this.timer);
					}
				}, 300)
			}
		}

		const goddess = {
			mood: '',
			acceptFlowers: function (flower) {
				if (flower && this.mood) {
					console.log('ok');
				} else {
					console.log('get out');
				}
			},
			changeMood: function () {//改变心情
				this.mood = Math.random() > 0.5 ? true : false;
			},
			initialMood: function () {//女神初始化心情,随后一直变化
				this.changeMood();
				setInterval(() => {
					this.changeMood();
				}, 500)
			}
		}

		goddess.initialMood();
		Ming.sendFlowers(goddess); //自己送花,看女神心情,有时候会被拒绝
		person.proxyFlower(goddess);//代理人帮你送一定会成功

代理模式模拟图片懒加载

	<div id='show'></div>//自己加点样式
//占位图片
		function occupyImage(dom) {
			const img = new Image();
			this.setSrc = (src) => {
				img.src = src;
			}
			document.getElementById(dom).appendChild(img);
		}

		//代理懒加载
		const proxyLazy = (function () {
			const lImg = new Image();
			const oImg = new occupyImage('show');
			lImg.onload = () => {
				setTimeout(function () {
					oImg.setSrc(lImg.src);
				}, 1000)
			}
			return function (occupy, lazay) {
				lImg.src = lazay;
				oImg.setSrc(occupy);
			}
		}())

		proxyLazy('https://dss2.bdstatic.com/70cFvnSh_Q1YnxGkpoWK1HF6hhy/it/u=2860146846,3945182706&fm=26&gp=0.jpg', 'https://dss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=1008541312,1832566743&fm=26&gp=0.jpg')

代理模式模拟对于开销很大的对象,延迟到真正需要它的时候才去执行。

	<div id='demo'>//自己加点样式
		前端开发
	</div>
	<button type="bg">add greenbg</button>
	<button type="fz">add fontsize</button>
	<button type="fw">add fontweight</button>
	<button type="cl">add bluecolor</button>
	<button type="op">add opacity</button>

	const demo = document.getElementById('demo');
	const btnArr = document.getElementsByTagName('button');
		function proxyStyle(func) {
			let cache = [];
			let timer;
			return function () {
				clearTimeout(timer);
				cache.push(this.getAttribute('type'));
				setTimeout(() => {
					func(demo, cache);
					cache = [];
				}, 2000)
			}
		};

		const newStyle = proxyStyle(changeStyle);

		function changeStyle(dom, styleArr) {
			const typeArr = {
				"bg": ['background', 'red'],
				"fz": ['font-ize', '20px'],
				"fw": ['font-weight', 'bold'],
				"cl": ['color', 'blue'],
				"op": ['opacity', '0.5']
			}
			if (styleArr.constructor === Array) {
				styleArr.forEach(ele => {
					dom.style[typeArr[ele][0]] = typeArr[ele][1];
				})
			} else {
				dom.style[typeArr[styleArr[0]]] = typeArr[styleArr[1]];
			}
		}
		//点击按钮总会延迟一段时间执行

代理模式模拟实现前端验证,验证成功后才可以进行其他操作。

<div>
    用户名: <input type="text" id='user' name='username' />
    <span id='userW'></span>
    密码: <input type="password" id='password' name='password' />
    <span id='passwordW'></span>
    邮箱: <input type="text" id='email' name='email'>
    <span id='emailW'></span>
    <span id='btn'>提交</span>
  </div>
//代理验证
		function request(){//验证成功发送请求
			console.log('ajax');
		}

		btn.onclick = function(){
			proxyRequest();
		}

		function Validator(){
			this.dom = [];//验证字段的原生dom
			this.wran = [];//警告信息的原生dom
		};
		
		Validator.prototype.add = function(dom,wranDom,verifcationArr){//添加验证信息
			const _this = this;
			this.wran.push(wranDom);
			verifcationArr.forEach(item=>{
				this.dom.push(function(){
					let arr = item.verifcation.split(':');
					let type = arr.shift();
					arr.unshift(dom.value);
					arr.push(item.errorMsg);

					let msg = _this.verifcation[type].apply(_this,arr);
					if(msg != true){
						wranDom.innerText = msg;
					}

					return msg;
				})
			})
		};
		Validator.prototype.start = function(){//所有验证信息的验证
			let flag = true;
			this.wran.forEach(ele=>{
				ele.innerText = '';
			})
			this.dom.forEach(ele=>{
				if(ele() != true){
					flag = false;
				}
			})
			return flag;
		}

		Validator.prototype.verifcation = {//已有的验证信息
			NotEmpty:function(value,errMsg){
				if(value == ''){
					return errMsg;
				}
				return true;
			},
			maxLength:function(value,length,errMsg){
				if(value != '' && value.length > length){
					return errMsg;
				}
				return true;
			},
			minLength:function(value,length,errMsg){
				if(value != '' && value.length < length){
					return errMsg;
				}
				return true;
			}
		}
		Validator.prototype.extend = function (config) {//扩展验证信息
      for (let prop in config) {
        Validator.prototype.verifcation[prop] = config[prop];
      }
		};
		
		let validator = new Validator();
		
		validator.extend({//扩展邮箱验证
      		isEmail: function (value, errMsg) {
        	if (value != '' && value.indexOf('@') <= -1) {
          	return errMsg;
        }
        return true;
      }
    })
		//代理
		let proxyRequest = (function(){
			//添加验证信息,格式需要固定格式
			validator.add(user, userW, [
        {
          verifcation: 'NotEmpty',
          errorMsg: '用户名不能为空'
        },
        {
          verifcation: 'maxLength:4',
          errorMsg: '用户名长度不能超过4'
        },
      ]);
      validator.add(password, passwordW, [
        {
          verifcation: 'NotEmpty',
          errorMsg: '密码不能为空'
        },
        {
          verifcation: 'minLength:6',
          errorMsg: '密码长度不能小于6'
        },
        {
          verifcation: 'maxLength:15',
          errorMsg: '密码长度不能大于15'
        }
			]);
			 validator.add(email, emailW, [
        {
          verifcation: 'NotEmpty',
          errorMsg: '邮箱不能为空'
        },
        {
          verifcation: 'isEmail',
          errorMsg: '邮箱格式不正确'
        }
      ])

			return function(){
				if(validator.start() == true){//验证成功
					request();
				}
			}
		}())
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值