圖片懶加載和預(yù)加載

圖片懶加載的原理是什么?

首先明白為什么要懶加載:

懶加載即延遲,對(duì)于圖片過多的頁(yè)面,為了加快頁(yè)面加載速度,我們需要將頁(yè)面內(nèi)未出現(xiàn)在可視區(qū)域內(nèi)的圖片先不做加載, 等到滾動(dòng)到可視區(qū)域后再去加載。
這樣一來頁(yè)面加載性能大幅提升,提高了用戶體驗(yàn)。
注:手機(jī)會(huì)自動(dòng)做懶加載

實(shí)現(xiàn)原理:

在頁(yè)面載入時(shí)將img標(biāo)簽內(nèi)的src指向一個(gè)小圖片,即占位圖或loading圖,將真實(shí)地址存放于一個(gè)自定義屬性data-src中。當(dāng)頁(yè)面滾動(dòng)時(shí),遍歷有data-src的img標(biāo)簽,判斷每個(gè)img是否進(jìn)入可視區(qū),當(dāng)某個(gè)img進(jìn)入了可視區(qū)域,就將真實(shí)地址賦值給該img的src并將該img的data-src刪除以避免重復(fù)判斷。
核心代碼:

<img src="https://i.loli.net/2017/08/08/5989307b6c87b.gif" data-xxx="${data.content[i].url}">
         
let images = document.querySelectorAll('img[data-xxx]')
  for(let i = 0; i <images.length; i++){
    if(出現(xiàn)在屏幕里(images[i])){
      images[i].src = images[i].getAttribute('data-xxx')
      images[i].removeAttribute('data-xxx')
    }

預(yù)加載:
預(yù)先加載所需資源

<link rel="prefetch" >

全部代碼:

<html lang="zh-Hans">
<head>
  <meta charset="UTF-8">
  <title>加載更多 Demo</title>
  <link rel="prefetch" >
  <style>
    *{padding:0; margin: 0; box-sizing: border-box;}
    *::before{box-sizing: border-box;}
    *::after{box-sizing: border-box;}
    ul,ol{list-style:none;}

    #list{
      max-width: 680px;
      margin: 0 auto;
      display: flex;
      flex-wrap: wrap;
      justify-content: space-between;
    }
    #list > li{
      width: calc(33.333333% - 10px);
    }
    #list > li img{
      width: 100%;
    }
    .loadMore{
      text-align: center; margin: 16px 0;
    }
    .oneToOne{
      padding-top: 100%;
      position: relative;
    }
    .oneToOne img{
      position: absolute;
      width: 100%;
      height: 100%;
      left: 0; top: 0;
    }
  </style>
</head>
<body>
  <ol id=list>
  </ol>
  <div class=loadMore>
    <button id="loadMoreButton" class=button>加載更多</button>
    <div style="height: 1000px;"></div>
  </div>
  
  <script>

let list = document.querySelector('#list')
for(var i=0; i<9; i++){
  let li = document.createElement('li')
  let div = document.createElement('div')
  div.className = 'oneToOne'
  let img = document.createElement('img')
  div.appendChild(img)
  img.src = '//via.placeholder.com/200x200?text=' + Math.random().toFixed(6)
  let p = document.createElement('p')
  p.textContent = `這是第 ${i+1} 段話`
  li.appendChild(div)
  li.appendChild(p)
  list.appendChild(li)
}

let n = 1
let hasNext = true
let 正在請(qǐng)求 = false
function loadMore(){
  if(正在請(qǐng)求){return}
  if(!hasNext){ return }
  let request = new XMLHttpRequest()
  request.open('GET', `./page-${n+1}.html`)
  request.onerror = function(){ 正在請(qǐng)求 = false }
  request.onload = function(){
    正在請(qǐng)求 = false
    n += 1
    let response = request.responseText
    // JSON.parse 輸入符合 JSON 語(yǔ)法的字符串,輸出 JSON 對(duì)應(yīng)的數(shù)據(jù) array/number/string
    let data = window.JSON.parse(response)
    for(let i = 0; i< data.content.length; i++){
      let liString = `
        <li>
          <div class=oneToOne>
            <img src="https://i.loli.net/2017/08/08/5989307b6c87b.gif" data-xxx="${data.content[i].url}">
          </div>
          <p>${data.content[i].text}</p>
        </li>
      `
      list.insertAdjacentHTML( 'beforeend', liString );
    }
    if(data.hasNextPage === false){
      hasNext = false
      loadMoreButton.textContent = '沒了'
    }
  }
  正在請(qǐng)求 = true
  request.send()
}

loadMoreButton.onclick = loadMore


window.onscroll = function(){
  if(出現(xiàn)在屏幕里(loadMoreButton) === true){
    //loadMoreButton.click()
    if(hasNext){ loadMore() }
  }

  let images = document.querySelectorAll('img[data-xxx]')
  for(let i = 0; i <images.length; i++){
    if(出現(xiàn)在屏幕里(images[i])){
      images[i].src = images[i].getAttribute('data-xxx')
      images[i].removeAttribute('data-xxx')
    }
  }
}




function 出現(xiàn)在屏幕里(element){
  var doc = document.documentElement;
  var top = (window.pageYOffset || doc.scrollTop)  - (doc.clientTop || 0);
  var viewport的高度 = doc.clientHeight
  var viewportOffset = element.getBoundingClientRect();
  // these are relative to the viewport, i.e. the window
  var 按鈕到viewport頂部的距離 = viewportOffset.top;
  if(按鈕到viewport頂部的距離 <= viewport的高度){
    return true
  }else{
    return false
  }
}
  </script>
</body>
</html>

  <style>
    .button {
      border: none;
      background: #3498db;
      background-image: linear-gradient(to bottom, #3498db, #2980b9);
      border-radius: 28px;
      color: #ffffff;
      font-size: 20px;
      padding: 10px 20px 10px 20px;
      text-decoration: none;
    }

    .button:hover {
      background: #3cb0fd;
      background-image: linear-gradient(to bottom, #3cb0fd, #3498db);
      text-decoration: none;
    }
  </style>
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 1、通過CocoaPods安裝項(xiàng)目名稱項(xiàng)目信息 AFNetworking網(wǎng)絡(luò)請(qǐng)求組件 FMDB本地?cái)?shù)據(jù)庫(kù)組件 SD...
    陽(yáng)明AI閱讀 16,203評(píng)論 3 119
  • 問答題47 /72 常見瀏覽器兼容性問題與解決方案? 參考答案 (1)瀏覽器兼容問題一:不同瀏覽器的標(biāo)簽?zāi)J(rèn)的外補(bǔ)...
    _Yfling閱讀 14,152評(píng)論 1 92
  • 運(yùn)動(dòng)是改變一個(gè)人慵懶狀態(tài)的辦法之一。 人吧,越閑越覺得不知所措,越動(dòng)越有精神。通過運(yùn)動(dòng),可以積攢一些能量,所以今日...
    葉子的心情雜貨鋪閱讀 226評(píng)論 0 0
  • 兒子上大學(xué)以后,每次回來或者去上學(xué)都要在網(wǎng)上買火車票。他第一次上學(xué)走,是我和他爸送的,在縣城火車站,我們?nèi)齻€(gè)在自動(dòng)...
    靜心專注閱讀 330評(píng)論 0 0
  • 何處尋 紅顏有約 誰(shuí)人知我心 卻道變 百日已斷腸 千年輪回 故人嘆 一生所愛 難得見此情 何處尋覓 少年事 來生續(xù)...
    我愛吃任何魚閱讀 231評(píng)論 1 3

友情鏈接更多精彩內(nèi)容