前端常用设计模式之代理模式
代理模式:在有耦合关系的两个对象之间建立代理对象, 代理对象起到类似中介的作用,如校验, 合并等.例子
虚拟代理:把开销 很大的对象,延迟到正在需要时候才创建 如图片懒加载. 文件一起上传
安全代理: 控制对象的访问权限.如注册验证, 如果你的用户名格式不正确, 代理对象控制, 不会发ajax请求, 智能推荐正确格式的用户名;
例子一: 屌丝追女神想送花, 条件:女生心情多变, 当女神心情好时候,收到花会说谢谢, so,屌丝找一个老司机帮自己观察, 老司机瞅着合适机会就通知屌丝送花;
心情不好时,收到花后果很严重 (老司机就是代理对象)
var diaosi = { sendFlower: function (girl) { girl.recieveFlower(); } } var girl = { mood: null, words:'', recieveFlower: function () { this.words = this.mood == 'good' ? "thanks" : 'get out' console.log (this.words) }, changeMood: function () {//girl心情不断变化,屌丝要拜托老司机送花 setInterval(() => { this.mood = Math.random() - 0.5 > 0 ? 'good' : "sad"; // console.log('gril的心情'+ this.mood) },300) } } var oldDriver = { watch: function(){ var timer = setInterval(() =>{ var mood = girl.mood; //监视心女神心情 if(mood == 'good'){ diaosi.sendFlower(girl); clearInterval(timer) } },300) } } girl.changeMood() cheng.watch()
例子二:图片预加载和懒加载代理; 控制图片的懒加载和预加载的发生时间和过程;
要按照顺序说的话,先懒加载:什么时候需要什么时候才加载,它针对的是全加载,就是把网页上所有的图片都加载完,增加网络请求的负担,造成请求资源浪费
再预加载: 完全onload了资源以后,才往dom里插入.它对应的是直接设置src和直接插入dom;造成加载过程中容易出现图片从上往下慢慢加一段段出现,加重了浏览器的渲染负担,
<style> html, body { height: 3000px; } button { position: absolute; top: 1800px; } div { position: absolute; top: 2000px; } </style> </head> <body> <div id="demo"></div> <button>开始加载</button> <script> var insertImg = (function () { var result = null; return function (id, src) { if (result) { return result; } var img = new Image() this.setSrc = function (src) { img.src = src; } document.getElementById(id).appendChild(img); result = this; } })() document.onscroll = function () { var oTop = demo.offsetTop; if (window.pageYOffset >= oTop) { proxy('http://n.sinaimg.cn/sinacn00/292/w476h616/20180404/2d8e-fytnfyn8190914.png')//真正的需要加载的图片 } } var proxy =(function(){//当事件触发时候,才去执行proxy请求图片,是懒加载 var oImg = new insertImg('demo');//如果有多个需要插入图片的div,demo不能写死 oImg.setSrc('http://n.sinaimg.cn/sinacn21/400/w800h1200/20180406/3ec4-fysuuyc3274232.jpg');//占位图片,资源一旦请求过,存在缓存里,其他的div也用 return function(src){//这段代码是预加载,设定了一个傀儡图片,傀儡图片的作用是请求真正的图片资源,当资源请求完成后就一次性渲染到dom里 var myImg = new Image(); myImg.onload = function () { oImg.setSrc(src) } myImg.src = src; } })()
例三:挨个点击许多小块后,颜色一起出现变化
<style> #wrapper{ height: 200px; width: 100%; text-align: center; border: 1px solid } #wrapper div{ display: inline-block; height: 100%; width: 200px; border: 1px solid; box-sizing: border-box; cursor: pointer; } button{ margin: 0 auto; } </style> </head> <div id="wrapper"> <div class="blue">blue</div> <div class="yellow">yellow</div> <div class="red">red</div> <div class="green">green</div> </div> <body> <script> function changeColor (div){ var color = div.className div.style.background = color } wrapper.onclick = function(e){ proxy(e.target) } var proxy = (function(){ var timer = null; var arr = []; return function(div){ clearTimeout(timer) arr.push(div); timer = setTimeout(() => { console.log(11111) arr.forEach(function(ele){ changeColor(ele) }) }, 2000); } })()
例四: 保护代理(见策略模式)
<style>
#wrapper{
height: 200px;
width: 100%;
text-align: center;
border: 1px solid
}
#wrapper div{
display: inline-block;
height: 100%;
width: 200px;
border: 1px solid;
box-sizing: border-box;
cursor: pointer;
}
button{
margin: 0 auto;
}
</style>
</head>
<div id="wrapper">
<div class="blue">blue</div>
<div class="yellow">yellow</div>
<div class="red">red</div>
<div class="green">green</div>
</div>
<body>
<script>
function changeColor (div){
var color = div.className
div.style.background = color
}
wrapper.onclick = function(e){
proxy(e.target)
}
var proxy = (function(){
var timer = null;
var arr = [];
return function(div){
clearTimeout(timer)
arr.push(div);
timer = setTimeout(() => {
console.log(11111)
arr.forEach(function(ele){
changeColor(ele)
})
}, 2000);
}
})()