index.html
<! DOCTYPEhtml>
<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>
<! -- Waterfall flow -->
<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>
Copy the code
1.js
// Delay request data
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;
/ / initialization
initdata();
/ / lazy loading
lazyload();
})
/ / initialization
const initdata = function initdata() {
let { datalist } = vue.state;
// Set the height according to the scale
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'));
// Sort from smallest to largest
group.sort((a,b) = > {
return a.h - b.h
})
// Container sort
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); }}})// Images load lazily
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){
// Display the image
target['src'] = target.getAttribute("img-data"); imgsob.unobserve(target); }})}// Bind listener events
let imgsob = new IntersectionObserver(Callback,config);
imgs.forEach((item,i) = >{ imgsob.observe(item); })}Copy the code
IntersectionObserver
Developer.mozilla.org/zh-CN/docs/…
{threshold:[0,1]} @3 */ config :{threshold:[0,1] //
let Callback = function Callback(e){
e = Array.from(e);
e.forEach((item,i) = > {
let {isIntersecting,target} = item;
if(isIntersecting){
// Display the image
target['src'] = target.getAttribute("img-data");
/ / cancelimgsob.unobserve(target); }})}let ob = new IntersectionObserver(Callback,config);
ob.observe(target);
Copy the code