您的位置:首页 > Web前端 > JavaScript

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

2020-04-06 07:19 1616 查看

代理模式

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

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

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

举栗

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

//女神根据心情好坏看是否接受小明的送花
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();
}
}
}())
  • 点赞
  • 收藏
  • 分享
  • 文章举报
屡次拒绝田馥甄 发布了8 篇原创文章 · 获赞 0 · 访问量 81 私信 关注
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: