懒加载+瀑布流

2,120 阅读1分钟

index.html

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }

        html,body {
            width: 100%;
            height: 100%;
        }

        .box {
            width: 70%;
            display: flex;
            justify-content: space-between;
            margin: auto;
        }

        .column {
            width: 230px;
        }

        .card {
            width: 220px;
            margin: 10px;
        }
    </style>
</head>

<body>
    <!-- 瀑布流 -->
    <div class="box">
        <div class="column">
            <div class="card">
                <!-- <img style="width: 200px;height: 100px;" src="./images/1.jpg" alt=""> -->
            </div>
        </div>
        <div class="column">
          
        </div>
        <div class="column">
           
        </div>
        <div class="column">
            
        </div>
    </div>
    <script src="./node_modules/axios/dist/axios.js"></script>
    <script src="1.js"></script>
</body>

</html>

1.js

// 延时请求数据
const getData = function getData() {
    return new Promise((resolve, reject) => {
        axios.get('./data.json').then((res) => {
            setTimeout(() => {
                resolve(res)
            }, 1000)
        })
    })
}

const state = function state() {
    this.state = {};
}
let vue = new state();

getData().then((res) => {
    vue.state.datalist = res.data;
    // 初始化
    initdata();
    // 懒加载
    lazyload();
})

// 初始化 
const initdata = function initdata() {
    let { datalist } = vue.state;
    // 根据比例 设置高度
    datalist.map((item, i) => {
        let { height, width } = item,
            w = 230,
            h = (w * height) / width;
        item.w = 230 + 'px';
        item.h = h + 'px';
    })

    for (let index = 0; index < datalist.length; index = index + 4) {
        let group = datalist.slice(index,index+4),
            columns = Array.from(document.getElementsByClassName('column'));
        // 从小到大排序
        group.sort((a,b) => {
            return a.h - b.h
        })
        // 容器排序
        columns.sort((a,b) => {
            return b.offsetHeight - a.offsetHeight
        })
        group.forEach((item,i) => {
            let cart = document.createElement('div');
            cart.className = 'card';
            cart.style.height = `${item.h}`;
            cart.innerHTML = cart.innerHTML + `
                <img style="width: ${item.w};height:${item.h};" src=''  img-data='${item.pic}'></img>
            `
            columns[i].append(cart);
        })
    }
}

//图片懒加载
const lazyload = function lazyload(){
    let imgs = Array.from(document.getElementsByTagName('img')),
        config = {
            threshold:[1]
        };
    const Callback = function Callback(e){
        e = Array.from(e);
        e.forEach((item,i) => {
            let {isIntersecting,target} = item;
            if(isIntersecting){
                // 把图片显示出来
                target['src'] = target.getAttribute("img-data");
                imgsob.unobserve(target);
            }
        })

    }
    // 绑定监听事件
    let imgsob = new IntersectionObserver(Callback,config);
    imgs.forEach((item,i) => {
        imgsob.observe(item);
    })
}

IntersectionObserver

developer.mozilla.org/zh-CN/docs/…

/*
	@1 用途监听视口交叉
	@2 config :{
		threshold:[0,1]   //0表示露出来一点就触发Callback    1表示全部出来才触发Callback
	}
	@3
*/
let Callback = function Callback(e){
    e = Array.from(e);
    e.forEach((item,i) => {
        let {isIntersecting,target} = item;
        if(isIntersecting){
            // 把图片显示出来
            target['src'] = target.getAttribute("img-data");
            //取消
            imgsob.unobserve(target);
        }
    })
}
let ob = new IntersectionObserver(Callback,config);
ob.observe(target);