echo图片懒加载

最近不是在学习设计模式吗,然后就看到了代理模式加载图片的样例,然后自己实现了一下,就发现,自己写的这货每次就只能加载一张图片,而且图片要放在哪也是个很严重的问题

然后就去了 gayhub 找了找了找流行的图片懒加载库,这一找,就找到了一个echo.j是,打开一看,源码只有100多行吧,震惊。。,看完源码,哎,木有上代理模式呀

仔细学习了下源码:觉得这种做法比较适合图片位置确定场景的吧,比如文章啊,一篇文章老长了,里面有蛮多图片散落在不同的地方,这样就比较合适,有可能有很多图片读者都不会翻到哪里,加载下来就浪费了

关键点:

1.如何判断元素距离出现在视野里的长度还有多少?以常见鼠标往下滚动,图片在下面为例

          

灵魂画手哈哈,,,;H1是视窗的高度,window.innerHeight可以获得,H2就是提供给使用者设置的offsetBottom

然后祭出一个大招!element.getBoundingClientRect(),就能得到元素相对于视窗的四个距离

            

 
  1. var H=Element.getboundingclientrect().top;

  2. var flag=H-(H1+H2);//当flag值小于0就代表可以开始加载图片了

  那么,看看源码里面是怎么写的:

 
  1. var offset = {//四个值由用户传入决定,默认为0

  2. t: ,

  3. b:,

  4. l: ,

  5. r:

  6. };

  7. var view = { //计算邻界的距离

  8. l: 0 - offset.l,

  9. t: 0 - offset.t,

  10. b: (root.innerHeight || document.documentElement.clientHeight) + offset.b,

  11. r: (root.innerWidth || document.documentElement.clientWidth) + offset.r

  12. };

  13. var isHidden = function (element) {

  14. return (element.offsetParent === null); //element.offsetParent 表示父元素,如果为null证明没有在添加到DOM里面,或者position值为fixed

  15. };

  16.  
  17. var inView = function (element, view) { //判断是否在视图中调用这个函数判断

  18. if (isHidden(element)) { //判断是否在界面上

  19. return false;

  20. }

  21.  
  22. var box = element.getBoundingClientRect(); //计算四边的距离是否满足条件

  23. return (box.right >= view.l && box.bottom >= view.t && box.left <= view.r && box.top <= view.b);

  24. };

  

2.已经有了是否加载的判断函数,那么如何做到图片的懒加载?

  先加载loadding小菊花图片,当满足懒加载的条件时候,切换img的src属性,

对于img元素的设置有两个比较重要的值一个是src,一个是data-echo ,(还有一个是背景图片,不太重要,忽略他)两个,src设置小菊花的地址,data-echo真实的地址;

那么所有页面元素都这样设置后,会有什么影响?

当所有图片都用设置src为同一值,也就是用同一张菊花图,加载完之后就可以通用了

img这个元素的特性就是,当设置了src属性,他会去先加载这张图图片,如果在js里面马上改变了img的src属性,他会同事再进行一次网络请求去加载你js设置的src地址的图片

但是 会先将html里面设置的src图片加载完,显示,你什么时候加载完第二个图片什么时候替换,如果你在第二张图片加载的时候又改变了src的值,,,那也是一样的,什么加载完什么时候显示,没加载完的情况下显示原来的

源代码:

 
  1. if (inView(elem, view)) {//是否满足加载条件

  2.  
  3. if (unload) {//如果设置超出了不加载,保存小菊花地址在data-echo-placeholder属性

  4. elem.setAttribute('data-echo-placeholder', elem.src);

  5. }

  6.  
  7. if (elem.getAttribute('data-echo-background') !== null) {//img的背景图片

  8. elem.style.backgroundImage = 'url(' + elem.getAttribute('data-echo-

  9. background') + ')';

  10. }

  11. //当ele的src不等于data-echo的值,也就是真蒸的图片地址,改变图片的src

  12. else if (elem.src !== (src = elem.getAttribute('data-echo'))) {

  13. elem.src = src;

  14. }

  15.  
  16. if (!unload) { //如果没有设置超出不加载,在这里就可以清除这些属性了

  17. elem.removeAttribute('data-echo');

  18. elem.removeAttribute('data-echo-background');

  19. }

  20.  
  21. callback(elem, 'load');

  22. }

  23. else if (unload && !!(src = elem.getAttribute('data-echo-placeholder'))) {

  24. //处理超出不加载图片的情况,把原来保存的小菊花图赋给elem的src

  25. //因为小菊花是最开始就加载好了的,所以图片切换回小菊花,不再加载之前设置的真实图片

  26. if (elem.getAttribute('data-echo-background') !== null) {

  27. elem.style.backgroundImage = 'url(' + src + ')';

  28. }

  29. else {

  30. elem.src = src;

  31. }

  32.  
  33. elem.removeAttribute('data-echo-placeholder');

  34. callback(elem, 'unload');

  35. }

  36. }

  37. if (!length) {

  38. echo.detach();//移除事件监听

  39. }

  

3,scroll函数节流

函数节流,两种方式:

1:在滚动的时候不会触发,滚动停下来才会隔一段时间触发

2:每隔一段事件都触发 

 
  1. //第一种方式,每次滚动过程中一直触发,每次都会新清除上一次的setTimout,添加一个新的setTimout

  2. var poll;

  3. function throttle(){

  4. clearTimeout(poll);

  5. poll=setTimeout(function(){

  6. echo.render();

  7. },delay||250)

  8. }

  

  

 
  1. var poll;
    function throttle(){

  2. if(poll){ //存在setTimout,不清除,直接返回

  3. return ;

  4. }

  5. clearTimout(poll);

  6. poll=setTimeout(function(){

  7. echo.render();

  8. poll=null; //允许再次添加定时器

  9. },delay||250)

  10. }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值