国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁(yè) > 編程 > JavaScript > 正文

Vue自定義圖片懶加載指令v-lazyload詳解

2019-11-19 16:42:53
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友

Vue是可以自定義指令的,最近學(xué)習(xí)過(guò)程中遇見了一個(gè)需要圖片懶加載的功能,最后參考了別人的代碼和思路自己重新寫了一遍。以下將詳細(xì)介紹如何實(shí)現(xiàn)自定義指令v-lazyload。

先看如何使用這個(gè)指令:  

<img v-lazyload="imageSrc" >

imageSrc是要加載的圖片的實(shí)際路徑。

為了實(shí)現(xiàn)這個(gè)指令,我們首先單獨(dú)建立一個(gè)文件,名字為lazyload.js.并填寫基本的代碼,如下:  

//Vue 圖片懶加載,導(dǎo)出模塊export default (Vue , options = {})=>{  //初始化的選項(xiàng),default是未加載圖片時(shí)顯示的默認(rèn)圖片  var init = {     default: 'https://gw.alicdn.com/tps/i1/TB147JCLFXXXXc1XVXXxGsw1VXX-112-168.png'  }  //addListener為Vue指令的具體實(shí)現(xiàn)功能函數(shù),我們這里為所有使用v-lazyload的指令的元素添加監(jiān)聽  //ele 是dom元素,binding是綁定的具體值,  //例如:<img v-lazyload="imageSrc" > ele是img binding是imageSrc  const addListenner = (ele,binding) =>{      }  //Vue自定義指令,lazyload為指令的名稱  Vue.directive('lazyload',{    inserted:addListener,    updated:addListener  })}

inserted 和 updated為Vue指令的執(zhí)行不同階段提供的鉤子函數(shù),查看Vue的官網(wǎng)可以看到一共有5個(gè)階段, 

指令定義函數(shù)提供了幾個(gè)鉤子函數(shù)(可選):

bind: 只調(diào)用一次,指令第一次綁定到元素時(shí)調(diào)用,用這個(gè)鉤子函數(shù)可以定義一個(gè)在綁定時(shí)執(zhí)行一次的初始化動(dòng)作。

inserted: 被綁定元素插入父節(jié)點(diǎn)時(shí)調(diào)用(父節(jié)點(diǎn)存在即可調(diào)用,不必存在于 document 中)。

update: 被綁定元素所在的模板更新時(shí)調(diào)用,而不論綁定值是否變化。通過(guò)比較更新前后的綁定值,可以忽略不必要的模板更新(詳細(xì)的鉤子函數(shù)參數(shù)見下)。

componentUpdated: 被綁定元素所在模板完成一次更新周期時(shí)調(diào)用。

unbind: 只調(diào)用一次, 指令與元素解綁時(shí)調(diào)用。

這里我們只用inserted和updated就夠了。

  接下來(lái)我們具體實(shí)現(xiàn)addListener的實(shí)現(xiàn)。我們的具體思路如下:

  1、先看看這個(gè)圖片是否需要懶加載。有兩種情況,一是圖片還沒(méi)到達(dá)可視區(qū)域,二是圖片已經(jīng)加載過(guò)了。

  2、然后監(jiān)聽窗口的scroll事件,判斷哪些圖片可以進(jìn)行懶加載了。

  這里我們需要一個(gè)需要進(jìn)行監(jiān)聽需要懶加載的圖片列表和一個(gè)需要記錄已經(jīng)加載過(guò)得圖片列表。另外為了方便數(shù)組的操作,我們加一個(gè)數(shù)組的remove方法。

繼續(xù)我們的代碼。

//Vue 圖片懶加載export default (Vue , options = {})=>{    //數(shù)組item remove方法  if(!Array.prototype.remove){    Array.prototype.remove = function(item){      if(!this.length) return      var index = this.indexOf(item);      if( index > -1){        this.splice(index,1);        return this      }    }  }  var init = {       default: 'https://gw.alicdn.com/tps/i1/TB147JCLFXXXXc1XVXXxGsw1VXX-112-168.png'   }    //需要進(jìn)行監(jiān)聽的圖片列表,還沒(méi)有加載過(guò)得   var listenList = [];  //已經(jīng)加載過(guò)得圖片緩存列表  var imageCatcheList = [];  //是否已經(jīng)加載過(guò)了  const isAlredyLoad = (imageSrc) => {      }  //檢測(cè)圖片是否可以加載,如果可以則進(jìn)行加載  const isCanShow = (item) =>{      };  //添加監(jiān)聽事件scroll  const onListenScroll = () =>{      }  //Vue 指令最終的方法  const addListener = (ele,binding) =>{    //綁定的圖片地址    var imageSrc = binding.value;    //如果已經(jīng)加載過(guò),則無(wú)需重新加載,直接將src賦值    if(isAlredyLoad(imageSrc)){      ele.src = imageSrc;      return false;    }    var item = {      ele:ele,      src:imageSrc    }    //圖片顯示默認(rèn)的圖片    ele.src = init.default;    //再看看是否可以顯示此圖片    if(isCanShow(item)){      return    }    //否則將圖片地址和元素均放入監(jiān)聽的lisenList里    listenList.push(item);        //然后開始監(jiān)聽頁(yè)面scroll事件    onListenScroll();  }  Vue.directive('lazyload',{    inserted:addListener,    updated:addListener  })}

接下來(lái)就幾個(gè)空方法的實(shí)現(xiàn)了。

isAlredyLoad ,判斷是否已經(jīng)加載過(guò)了這個(gè)圖片

const isAlredyLoad = (imageSrc) => {    if(imageCatcheList.indexOf(imageSrc) > -1){      return true;    }else{      return false;    }  }

isCanShow 圖片是否進(jìn)入可視區(qū)域,如果已經(jīng)進(jìn)入則進(jìn)行加載

//檢測(cè)圖片是否可以加載,如果可以則進(jìn)行加載  const isCanShow = (item) =>{    var ele = item.ele;    var src = item.src;    //圖片距離頁(yè)面頂部的距離    var top = ele.getBoundingClientRect().top;    //頁(yè)面可視區(qū)域的高度    var windowHeight = window.innerHight;    //top + 10 已經(jīng)進(jìn)入了可視區(qū)域10像素    if(top + 10 < window.innerHeight){      var image = new Image();      image.src = src;      image.onload = function(){        ele.src = src;        imageCatcheList.push(src);        listenList.remove(item);      }      return true;    }else{      return false;    }  };

onListenScroll監(jiān)聽滾動(dòng)事件,并且檢測(cè)是否進(jìn)入可視區(qū)域。

const onListenScroll = () =>{    window.addEventListener('scroll',function(){      var length = listenList.length;      for(let i = 0;i<length;i++ ){        isCanShow(listenList[i]);      }    })  }

最終我們的代碼如下:

//Vue 圖片懶加載export default (Vue , options = {})=>{  if(!Array.prototype.remove){    Array.prototype.remove = function(item){      if(!this.length) return      var index = this.indexOf(item);      if( index > -1){        this.splice(index,1);        return this      }    }  }  var init = {    lazyLoad: false,    default: 'https://gw.alicdn.com/tps/i1/TB147JCLFXXXXc1XVXXxGsw1VXX-112-168.png'  }  var listenList = [];  var imageCatcheList = [];  const isAlredyLoad = (imageSrc) => {    if(imageCatcheList.indexOf(imageSrc) > -1){      return true;    }else{      return false;    }  }  //檢測(cè)圖片是否可以加載,如果可以則進(jìn)行加載  const isCanShow = (item) =>{    var ele = item.ele;    var src = item.src;    //圖片距離頁(yè)面頂部的距離    var top = ele.getBoundingClientRect().top;    //頁(yè)面可視區(qū)域的高度    var windowHeight = window.innerHight;    //top + 10 已經(jīng)進(jìn)入了可視區(qū)域10像素    if(top + 10 < window.innerHeight){      var image = new Image();      image.src = src;      image.onload = function(){        ele.src = src;        imageCatcheList.push(src);        listenList.remove(item);      }      return true;    }else{      return false;    }  };  const onListenScroll = () =>{    window.addEventListener('scroll',function(){      var length = listenList.length;      for(let i = 0;i<length;i++ ){        isCanShow(listenList[i]);      }    })  }  //Vue 指令最終的方法  const addListener = (ele,binding) =>{    //綁定的圖片地址    var imageSrc = binding.value;    //如果已經(jīng)加載過(guò),則無(wú)需重新加載,直接將src賦值    if(isAlredyLoad(imageSrc)){      ele.src = imageSrc;      return false;    }    var item = {      ele:ele,      src:imageSrc    }    //圖片顯示默認(rèn)的圖片    ele.src = init.default;    //再看看是否可以顯示此圖片    if(isCanShow(item)){      return    }    //否則將圖片地址和元素均放入監(jiān)聽的lisenList里    listenList.push(item);        //然后開始監(jiān)聽頁(yè)面scroll事件    onListenScroll();  }  Vue.directive('lazyload',{    inserted:addListener,    updated:addListener  })}

使用時(shí)需要在主文件中引入這個(gè)文件,并且vue.use();

import LazyLoad from 'lazyLoad.js'Vue.use(LazyLoad);

并且在需要懶加載的圖片上均按照如下使用v-lazyload指令即可

<img v-lazyload="imageSrc" >

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持武林網(wǎng)。

發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 邮箱| 天峻县| 扎赉特旗| 水城县| 玉门市| 威信县| 乐山市| 磐石市| 常宁市| 正阳县| 祁阳县| 孝昌县| 宜州市| 双江| 延安市| 无极县| 静海县| 罗甸县| 通许县| 康保县| 龙陵县| 丰原市| 曲水县| 苏尼特左旗| 利川市| 固始县| 仪陇县| 中江县| 绥阳县| 进贤县| 星子县| 江城| 禄劝| 茂名市| 霍州市| 宁强县| 吕梁市| 汤原县| 普定县| 隆子县| 若尔盖县|