思路:/*
1.獲取資料:封裝成一個函式,去實現獲取資料的動作
2.渲染資料:把從後臺獲取到的資料展示到頁面上,按照列展示的,迴圈後臺給的陣列,
然後把每一條資料拼接好,新增到長度最小的一列,這裡封裝了一個最小列的方法,
把元素集合轉成陣列,然後按照clientHeight 進行排序,由此找到最低那個li.
3.實現滾動載入更多資料,當長度最小的那個li的底部漏出時就載入新的資料,loadmore
為了,防止一次性請求多次,多了一個flag判斷,只有當flag為false時,才去執行新資料請求載入
當請求開始時 flag設定為true 渲染成功,我們把flag再設定為false。
4.實現圖片懶載入的操作,loadImg loadAll當圖片還沒有出現在可視視窗的時候不去載入圖片,只有當圖片漏出來一半時再去載入
5.預載入 ,當圖片要在展示成真正的圖片時 先用預設圖展示,然後在利用js建立一個臨時的圖片。
讓這個臨時的圖片去 請求遠端 真實的圖片, 當請求成功後再把真實圖片地址賦給頁面的那個img標籤。
6.fadeIn:實現圖片的漸現,利用定時器對img進行opacity的累加操作
效能優化:每一個圖表對應一個div,會有但bug,優化成 所有圖示對應一個div 控制div中的內容
*/
let body = document.getElementsByClassName('body')[0],
olis = document.querySelectorAll('.body li'),
oImg = body.getElementsByTagName('img')
let flag = false;//代表新資料渲染完成 什麼時候 flag應該是個true ??//新資料一請求,就把 flag 變
let n = 0;
//獲取資料
function getData() {
flag = true;
n++;
let xhr = new XMLHttpRequest();
xhr.open('get', './data.json', true);
xhr.onreadystatechange = function () {
if (xhr.readyState == 4 && /200|304/.test(xhr.status)) {//請求成功
console.log(JSON.parse(xhr.response))
let data = JSON.parse(xhr.response)
render(data)//獲取新資料 渲染頁面
flag = false;//新資料渲染完成後的操作
loadAll();
}
}
xhr.send();
}
getData();
function render(data) {
//data 後臺給的陣列
//迴圈陣列 拼接字串 拼接好的字串放進頁面
let str = '';
data.forEach(item => {
let { pic, author, desc, height } = item
// str = `
// <div class="img_box">
// <img realSrc="${pic}" realSrc="./img/1.jpg" alt="" style='height:${height}px'>
// <P class="desc">${desc}</P>
// <p class="author">${author}</p>
// </div>`
// //str是新拼接出來的一個快,我們需要決定的事 這個快放在哪個li中
// // olis[index % 5].innerHTML += str;
// let temp = getMinLi();//找出最短li
// //把要增加的這一項放到最低的li中
// temp.innerHTML += str;
str = `
<img realSrc="${pic}" realSrc="./img/1.jpg" alt="" style='height:${height}px'>
<P class="desc">${desc}</P>
<p class="author">${author}</p>
`
let temp = getMinLi();//找出最短li
let div = document.createElement('div')
div.className = 'img_box';
div.innerHTML = str;
temp.appendChild(div);
})
}
//找最短的li
function getMinLi() {
//找最短的li
let ary = [...olis].sort((a, b) => {
return a.clientHeight - b.clientHeight;
})
return ary[0];
}
//第三部 滾動載入新資料
window.onscroll = function () {
loadMore()
loadAll()
}
function loadMore() {
//最短的那個li漏出底部的時候 就載入新資料
if (n >= 3) return;//滑動滾輪載入兩次圖片,如果不設定就無限載入
let li = this.getMinLi();
if (this.utils.offset(li).t + li.clientHeight <= document.documentElement.scrollTop + this.utils.winH().h) {
//需要等新資料渲染到頁面後 再去載入新資料
if (!flag) {
console.log(666)
getData();
}
}
}
function loadAll() {
[...oImg].forEach(item => {
loadImg(item)
})
}
function loadImg(ele) {
if (ele.myLoad) return
//懶載入
if (utils.offset(ele).t + ele.clientHeight / 2 <= document.documentElement.scrollTop + utils.winH().h) {
//圖片漏出來一半
let realSrc = ele.getAttribute('realSrc');
// ele.src = realSrc;
let temp = new Image();
temp.src = realSrc;//讓臨時圖片去請求真實的圖片地址
temp.onload = function () {
//圖片從遠端拿到了本地
ele.src = realSrc;
ele.myLoad = true;//載入過之後就不再載入
fadeIn(ele)
}
temp = null;
}
}
//預載入
function fadeIn(ele) {
ele.style.opacity = 0;
let n = 0;
ele.timer = setInterval(() => {
n += 0.01;
if (n >= 1) {
n = 1;
clearInterval(ele.timer)
}
ele.style.opacity = n;
}, 10)
}
//具體程式碼如下
https://github.com/wdy15632628358/zhengshike2/blob/master/19-10/week4/day1/%E7%80%91%E5%B8%83%E6%B5%81.zip
複製程式碼