JavaScript - 圖片懶加載

一. 為什么需要圖片懶加載瞳别?

  • 每一張圖片都需要一個(gè)http請(qǐng)求獲取src,如果首頁(yè)有大量圖片壹蔓,加載時(shí)間會(huì)變長(zhǎng)趟妥,用戶體驗(yàn)不好。

二. 懶加載原理佣蓉?有什么好處披摄?

  • 用戶其實(shí)不關(guān)心屏幕看不到的地方亲雪,懶加載類似于組件的按需加載,在沒用到的時(shí)候暫時(shí)不請(qǐng)求內(nèi)容疚膊,在需要的時(shí)候再去發(fā)請(qǐng)求义辕。
  • 原理:在用戶看不到的時(shí)候使用loading圖占位,真正的圖片內(nèi)容等到圖片處于可視范圍再請(qǐng)求寓盗。

三. 實(shí)現(xiàn)

問題1:如何判斷圖片處于可視范圍终息?
  • 兩個(gè)主要API:

Element.getBoundingClientRect():返回元素的大小及其相對(duì)于視口的位置。
window.innerHeight:瀏覽器窗口的視口(viewport)高度(以像素為單位)贞让;如果有水平滾動(dòng)條周崭,也包括滾動(dòng)條高度

  • 使用Element.getBoundingClientRect().top獲取圖片距離視窗頂部的距離。
  • 使用window.innerHeight獲取視窗高度喳张。
  • 判斷圖片是否在可視范圍续镇,只需要判斷Element.getBoundingClientRect().top <= window.innerHeight
問題2:圖片的src暫存的是loading圖,如何獲取真正的圖片內(nèi)容销部?
  • 自定義data-src屬性摸航,用于存放真正的地址,當(dāng)圖片到了可視范圍就使用真正的src替換loading圖舅桩。
問題3:如何動(dòng)態(tài)獲取視窗變化酱虎?
  • 監(jiān)聽瀏覽器的滾動(dòng)條事件,觸發(fā)判斷是否加載的回調(diào)擂涛。
問題4:滾動(dòng)時(shí)間觸發(fā)太頻繁读串,如何優(yōu)化,減少重復(fù)判斷撒妈?
  • 對(duì)判斷方法進(jìn)行函數(shù)防抖恢暖。
問題5:已經(jīng)加載過的圖片怎么區(qū)分?(避免重復(fù)加載)
  • 將已經(jīng)加載過的圖片從圖片列表中刪除狰右。
完整代碼
<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title></title>
        <style>
            .container{
                width:400px;
            }
            img{
                width:400px;
                height:600px;
            }
        </style>
    </head>
    <body>
        <div class="container">
            <img src="./loading.gif" data-src="./smile.jpg" class="lazy">
            <img src="./loading.gif" data-src="./smile.jpg" class="lazy">
            <img src="./loading.gif" data-src="./smile.jpg" class="lazy">
            <img src="./loading.gif" data-src="./smile.jpg" class="lazy">
            <img src="./loading.gif" data-src="./smile.jpg" class="lazy">
            <img src="./loading.gif" data-src="./smile.jpg" class="lazy">
            <img src="./loading.gif" data-src="./smile.jpg" class="lazy">
            <img src="./loading.gif" data-src="./smile.jpg" class="lazy">
            <img src="./loading.gif" data-src="./smile.jpg" class="lazy">
            <img src="./loading.gif" data-src="./smile.jpg" class="lazy">
            <img src="./loading.gif" data-src="./smile.jpg" class="lazy">
            <img src="./loading.gif" data-src="./smile.jpg" class="lazy">
            <img src="./loading.gif" data-src="./smile.jpg" class="lazy">
        </div>
        <script>
        class LazyLoad{
            constructor(className){
                this.imgList = [...document.querySelectorAll(className)];
                this.judge();
                this.bindEvent();
            }
            // 防抖函數(shù)
            debounce(fn,delay){
                let timer = null;
                return function(){
                    if(timer){
                        clearTimeout(timer);
                    }
                    timer = setTimeout(fn,delay);
                }
            }
            // 監(jiān)聽滾動(dòng)條
            bindEvent(){
                window.addEventListener('scroll',this.debounce(()=>{
                    this.imgList.length && this.judge();                  
                },200))
            }
            // 判斷是否在可視范圍
            judge(){
                let imgs = this.imgList;
                for(let i = 0;i < imgs.length;i++){
                  if(imgs[i].getBoundingClientRect().top <= window.innerHeight){
                        this.load(imgs[i],i);
                    }
                }
            }
            // 將loading圖替換為真實(shí)地址杰捂,加載圖片
            load(el,index){
                let src = el.getAttribute('data-src');
                el.src = src;
                this.imgList.splice(index,1);
            }
        }
        const lazy = new LazyLoad('.lazy')
        </script>
    </body>
</html>
  • 只需要給需要懶加載的圖片加上lazy樣式即可。


?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末棋蚌,一起剝皮案震驚了整個(gè)濱河市嫁佳,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌谷暮,老刑警劉巖蒿往,帶你破解...
    沈念sama閱讀 206,311評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異坷备,居然都是意外死亡熄浓,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,339評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門省撑,熙熙樓的掌柜王于貴愁眉苦臉地迎上來赌蔑,“玉大人,你說我怎么就攤上這事竟秫⊥薰撸” “怎么了?”我有些...
    開封第一講書人閱讀 152,671評(píng)論 0 342
  • 文/不壞的土叔 我叫張陵肥败,是天一觀的道長(zhǎng)趾浅。 經(jīng)常有香客問我,道長(zhǎng)馒稍,這世上最難降的妖魔是什么皿哨? 我笑而不...
    開封第一講書人閱讀 55,252評(píng)論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮纽谒,結(jié)果婚禮上证膨,老公的妹妹穿的比我還像新娘。我一直安慰自己鼓黔,他們只是感情好央勒,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,253評(píng)論 5 371
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著澳化,像睡著了一般崔步。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上缎谷,一...
    開封第一講書人閱讀 49,031評(píng)論 1 285
  • 那天井濒,我揣著相機(jī)與錄音,去河邊找鬼列林。 笑死眼虱,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的席纽。 我是一名探鬼主播捏悬,決...
    沈念sama閱讀 38,340評(píng)論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼润梯!你這毒婦竟也來了过牙?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 36,973評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤纺铭,失蹤者是張志新(化名)和其女友劉穎寇钉,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體舶赔,經(jīng)...
    沈念sama閱讀 43,466評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡扫倡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,937評(píng)論 2 323
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片撵溃。...
    茶點(diǎn)故事閱讀 38,039評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡疚鲤,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出缘挑,到底是詐尸還是另有隱情集歇,我是刑警寧澤,帶...
    沈念sama閱讀 33,701評(píng)論 4 323
  • 正文 年R本政府宣布语淘,位于F島的核電站诲宇,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏惶翻。R本人自食惡果不足惜姑蓝,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,254評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望吕粗。 院中可真熱鬧纺荧,春花似錦、人聲如沸溯泣。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,259評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)垃沦。三九已至客给,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間肢簿,已是汗流浹背靶剑。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評(píng)論 1 262
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留池充,地道東北人桩引。 一個(gè)月前我還...
    沈念sama閱讀 45,497評(píng)論 2 354
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像收夸,于是被迫代替她去往敵國(guó)和親坑匠。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,786評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容