溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

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

發(fā)布時(shí)間:2020-06-07 00:00:58 來源:網(wǎng)絡(luò) 閱讀:650 作者:吳金瑞 欄目:網(wǎng)絡(luò)安全

    

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

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

  

<img v-lazyload="p_w_picpathSrc" >

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

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

  

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

export  (Vue , options = {})=> init =: 'https://gw.alicdn.com/tps/i1/TB147JCLFXXXXc1XVXXxGsw1VXX-112-168.png'  //例如:<img v-lazyload="p_w_picpathSrc" > ele是img binding是p_w_picpathSrc
'lazyload'

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

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)用,而不論綁定值是否變化。通過比較更新前后的綁定值,可以忽略不必要的模板更新(詳細(xì)的鉤子函數(shù)參數(shù)見下)。

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

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

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

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

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

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

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

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

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

export  (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
            }
        }
    }
 init =: 'https://gw.alicdn.com/tps/i1/TB147JCLFXXXXc1XVXXxGsw1VXX-112-168.png' listenList = p_w_picpathCatcheList == (p_w_picpathSrc) =>
    const isCanShow = (item) =>= () =>
    const addListener = (ele,binding) =>
         p_w_picpathSrc =
        =  item =
        ele.src = init.
        'lazyload'

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

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

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

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

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

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

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

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

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

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

 

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

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

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

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

最終我們的代碼如下:

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

//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 p_w_picpathCatcheList = [];

    const isAlredyLoad = (p_w_picpathSrc) => {        if(p_w_picpathCatcheList.indexOf(p_w_picpathSrc) > -1){            return true;
        }else{            return false;
        }
    }    //檢測圖片是否可以加載,如果可以則進(jìn)行加載
    const isCanShow = (item) =>{        var ele = item.ele;        var src = item.src;        //圖片距離頁面頂部的距離
        var top = ele.getBoundingClientRect().top;        //頁面可視區(qū)域的高度
        var windowHeight = window.innerHight;        //top + 10 已經(jīng)進(jìn)入了可視區(qū)域10像素
        if(top + 10 < window.innerHeight){            var p_w_picpath = new Image();
            p_w_picpath.src = src;
            p_w_picpath.onload = function(){
                ele.src = src;
                p_w_picpathCatcheList.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 p_w_picpathSrc = binding.value;        //如果已經(jīng)加載過,則無需重新加載,直接將src賦值
        if(isAlredyLoad(p_w_picpathSrc)){
            ele.src = p_w_picpathSrc;            return false;
        }        var item = {
            ele:ele,
            src:p_w_picpathSrc
        }        //圖片顯示默認(rèn)的圖片
        ele.src = init.default;        //再看看是否可以顯示此圖片
        if(isCanShow(item)){            return
        }        //否則將圖片地址和元素均放入監(jiān)聽的lisenList里        listenList.push(item);        
        //然后開始監(jiān)聽頁面scroll事件        onListenScroll();
    }

    Vue.directive('lazyload',{
        inserted:addListener,
        updated:addListener
    })
}

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

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

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

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

<img v-lazyload="p_w_picpathSrc" >


向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請(qǐng)聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI