Vue 结合节流函数实现懒加载插件

416 阅读3分钟

思路:这个插件是为懒加载图片的,一是img 的src图片,二是div的背景图,设置background-image: 当文档对象模型、CSS对象模型和渲染树被构造完成后, 开始请求外部资源之前,浏览器会检测CSS规则是怎么应用到DOM上的。 如果浏览器检测到CSS引用的外部资源并没有应用到已存在的DOM节点上,浏览器就不会请求这些资源。 设置全局指令lazy,如果是background-image ,则设置v-lazy='img1'传参数给函数,添加显示有设置背景图片的类,img1-visible。

二者都实现懒加载,图片都需要设置宽高来占位。 注意:img的src 设置本地的图片时,需要在data中用require引入。

插件:index.js

/**
 * 当文档对象模型、CSS对象模型和渲染树被构造完成后,
 * 开始请求外部资源之前,浏览器会检测CSS规则是怎么应用到DOM上的。
 * 如果浏览器检测到CSS引用的外部资源并没有应用到已存在的DOM节点上,浏览器就不会请求这些资源
 */

function throttle(fn, delay, atleast,el,value) {
    let timer = null
    let previous = null
    return function () {
        let now = +new Date()
        if (!previous) previous = now
        if (atleast && now - previous > atleast) {
            fn(el,value)
            previous = now
            clearTimeout(timer)
        } else {
            clearTimeout(timer)
            timer = setTimeout(function () {
                fn(el,value)
                previous = null
            }, delay)
        }
    }
}
const viewHieght = document.documentElement.clientHeight;
function isVisible(el) {
  const rect = el.getBoundingClientRect();
//   console.log("rec",rect);

  return rect.bottom >= 0 && rect.top < viewHieght ? true : false;
}
function lazyLoad(el,value) {
  const tagName = el.tagName;
//   console.log("tagName", tagName);
 
  if (tagName == "IMG" && isVisible(el)) {
    if (!el.dataset.original) return;
    !(function() {
      //而将运算符加载函数定义的前面,则是将函数看做一个整体,然后再调用这个函数,并对返回的结构进行逻辑运算
      var img = new Image();
      img.src = el.dataset.original;
      console.log(el.dataset.original)
      img.onload = function() {
        el.src = img.src;
      };
       el.removeAttribute("data-original");
    })();
  }
  if(tagName == "DIV" && isVisible(el)){  // 此时设置包含background-image的类
    el.classList.add(value+"-visible") 
  }
}

const obj = {
  install(Vue) {
    Vue.directive("lazy", {
      bind: function(el,binding) {
        // lazyLoad(el,binding);
        window.addEventListener('scroll', throttle(lazyLoad, 1000, 100 ,el,binding.value))
      },
      inserted: function(el,binding) {
        // lazyLoad(el,binding.value);
      },
    });
  },
};

export default obj;

main.js 中引入

import  lazyPlugin from "./lazyLoad";
Vue.use(lazyPlugin)

img懒加载引用:

<!-- v-lazy 直接调用本地图片地址 需要用require引入-->
  <img alt="Vue logo" v-lazy :data-original="url" src />
<!-- v-lazy 直接调用外网图片地址-->
   <div class="container">
       <img alt="Vue logo" v-lazy data-original="https://pic2.zhimg.com/80/v2-c3c7a7996ae3e40e2d1c01ea132356ff_720w.jpg" src="" />
       <img alt="Vue logo" v-lazy data-original="https://pic1.zhimg.com/80/v2-9b9d67f88bb5fdbc34a652a641cfda48_720w.jpg" src="" />
       <img alt="Vue logo" v-lazy data-original="https://pic1.zhimg.com/80/v2-3513570260a9e273b8aa5499718bf784_720w.jpg" src="" />
       <img alt="Vue logo" v-lazy data-original="https://pic1.zhimg.com/80/v2-3717f52544ee146404594e8845e620d9_720w.jpg" src="" />
       <img alt="Vue logo" v-lazy data-original="https://pic4.zhimg.com/80/v2-8c4aff083676684725e4a3e013f278cf_720w.jpg" src="" />
       <img alt="Vue logo" v-lazy data-original="https://pic4.zhimg.com/80/v2-e3c7380d78088a92989672917b3c0bea_720w.jpg" src="" />
       <img alt="Vue logo" v-lazy data-original="https://pic2.zhimg.com/80/v2-eed3e915b606295050fa21ca61925fc5_720w.jpg" src="" />
       <img alt="Vue logo" v-lazy data-original="https://pic2.zhimg.com/80/v2-0f2e68bea3342b21e0e95e659faa9b8a_720w.jpg" src="" />
       <img alt="Vue logo" v-lazy data-original="https://pic2.zhimg.com/80/v2-b1e578b6c917f9536ae06c988ddcac4b_720w.jpg" src="" />
  </div>
  
  
  data() {
    return {
      url: require("@/assets/logo.png")
    };
  }
  

background-image懒加载引用:

  <div class="container">
      <div class="happy" v-lazy="`img1`"></div>
      <div class="happy" v-lazy="`img2`"></div>
      <div class="happy" v-lazy="`img3`"></div>
      <div class="happy" v-lazy="`img4`"></div>
      <div class="happy" v-lazy="`img5`"></div>
      <div class="happy" v-lazy="`img6`"></div>
      <div class="happy" v-lazy="`img7`"></div>
      <div class="happy" v-lazy="`img8`"></div>
      <div class="happy" v-lazy="`img9`"></div>
      <div class="happy" v-lazy="`img10`"></div>
      <div class="happy" v-lazy="`img11`"></div>
      <div class="happy" v-lazy="`img12`"></div>
    </div>
  </div>
  
  .img1-visible{
  background-size: 100% 100%;
  background-image: url('../img/popups/wx_msg.png');
}
.img2-visible{
  background-size: 100% 100%;
  background-image: url('../img/popups/currency.png');
}
.img3-visible{
  background-size: 100% 100%;
  background-image: url('../img/popups/wx_share_peaple.png');
}
.img4-visible{
  background-size: 100% 100%;
  background-image: url('../img/popups/popup_bg.png');
}
.img5-visible{
  background-size: 100% 100%;
  background-image: url('../img/skin_activity/img_limit.png');
}
.img6-visible{
  background-size: 100% 100%;
  background-image: url('../img/skin_activity/img_limit_ph.png');
}
.img7-visible{
  background-size: 100% 100%;
  background-image: url('../img/wash_wall/3.png');
}
。。。。