思路:/*
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
复制代码