实战:ajax获取图片数据,实现瀑布流功能
什么是瀑布流?
瀑布流就是指按需加载。 也就是懒加载,而预加载是指事先加载好,需要的时候插入到指定的地方。
js/ajax.js
// ajax函数 用来与后端交互 (请求类型POST GET DELETE PUT HEAD, 请求地址, callback请求的回调函数,参数, 是否异步)
function ajax(method, url, callback, data, flag) {
// xhr 用来存储请求与响应的信息
var xhr = null;
if(window.XMLHttpRequest) {
xhr = new XMLHttpRequest();
}else {
xhr = new ActiveXObject('Microsoft.XMLHttp');
}
// 监听数据请求状态 监听状态readyState的变化
xhr.onreadystatechange = function() {
// 1 2 3
if(xhr.readyState == 4) {
// 4xx url data
if(xhr.status == 200) {
callback(xhr.responseText);
}else {
console.log('error');
}
}
}
method = method.toUpperCase();
// get 请求 把数据拼接在地址身上
if(method == 'GET') {
// 建立连接
xhr.open(method, url + '?' + data, flag);
// 发出请求
xhr.send();
// post 请求需要把数据放在请求体里面 不拼接地址
}else if(method == 'POST') {
// 建立连接
xhr.open(method, url, flag);
// 前端告诉后端 我的数据是什么格式的 key=value&key1=value1
xhr.setRequestHeader('Content-type','application/x-www-form-urlencoded');
// 传递数据 发出请求i
xhr.send(data);
}
}
./index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<link rel="stylesheet" href="./css/index.css">
</head>
<body>
<div class="wrapper">
<ul>
<li>
<div class="item">
<img src="./image/0.png" alt="">
<p>lalalall </p>
</div>
</li>
<li>
<div class="item">
<img src="./image/1.png" alt="">
<p>text</p>
</div>
</li>
<li>
<div class="item">
<img src="./image/2.png" alt="">
<p>imgage2</p>
</div>
</li>
<li>
<div class="item">
<img src="./image/3.png" alt="">
<p>xxxxx</p>
</div>
</li>
</ul>
</div>
<script src="./js/ajax.js"></script>
<script src="./js/index.js"></script>
</body>
</html>
data.json
[
{
"height":"1090",
"id":"662881",
"image":"http://www.wookmark.com/images/original/662881_wookmark.jpg",
"preview":"http://www.wookmark.com/images/thumbs/662881_wookmark.jpg",
"referer":"https://www.inspirationde.com/image/75082/",
"title":"Wicked November by Krzysztof Iwanski on Inspirationde",
"url":"http://www.wookmark.com/image/662881/wicked-november-by-krzysztof-iwanski-on-inspirationde",
"width":"770"
},
{
"height":"514",
"id":"654599",
"image":"http://www.wookmark.com/images/original/662880_wookmark.jpg",
"preview":"http://www.wookmark.com/images/thumbs/662880_wookmark.jpg",
"referer":"http://nofilmschool.com/2017/06/hackintosh-101-beginners-guide-to-building-your-own-4k-editing-machine",
"title":"Hackintosh 101: How to Build a 4K Editing Machine for Half the Purchase Price of a Mac",
"url":"http://www.wookmark.com/image/654599/hackintosh-101-how-to-build-a-4k-editing-machine-for-half-the-purchase-price-of-a-mac",
"width":"639"
}
]
./css/index.css
* {
padding: 0;
margin: 0;
list-style: none;
}
.wrapper {
width: 80%;
margin: 0 auto;
border: 1px solid #000;
}
.wrapper ul {
overflow: hidden;
}
.wrapper ul li {
float: left;
width: 25%;
/* padding: 10px; */
/* box-sizing: border-box; */
}
.item {
margin: 10px;
}
.item img {
width: 100%;
}
.item p {
font-size: 14px;
}
./js/index.js
// 请求数据页码
var page = 1;
// 存储页面上的li
var oLi = document.getElementsByTagName('li');
// 每张图片的宽度
var oDivWidth = document.getElementsByClassName('item')[0].offsetWidth;
console.log(oDivWidth);
// 请求结束 (当获取数据为空的时候停止翻页)
var flag = false;
// 获取数据
function getData() {
ajax('GET', './data.json', function (res) {
// console.log(res);
var data = JSON.parse(res);
// 渲染页面
renderDom(data);
if (!data.length || page == 5) {
flag = true;
}
}, 'page=' + page , true);
}
function renderDom(data) {
// 便利数据并插入到页面中那个
for (var i = 0; i < data.length; i++) {
var minIndex = getMinLi().minIndex;
var oDiv = document.createElement('div');
oDiv.className = 'item';
var img = new Image();
img.src = data[i].image;
// 设置图片高度 img.height 是真实页面上图片的高度 oDivWIdth是真实页面上图片的高度
// data[i].height/width 正常图片的高度/宽度
// 图片宽高比不变 a / b = c/ d ===> a = c / d * b = c * b / d
img.height = oDivWidth * data[i].height / data[i].width;
var oP = document.createElement('p');
oP.innerText = data[i].title;
oDiv.appendChild(img);
oDiv.appendChild(oP);
oLi[minIndex].appendChild(oDiv);
}
}
// 查找最短的li 返回最短li的索引值以及其高度
function getMinLi() {
// 最短li的索引值
var minIndex = 0;
// 最短li的高度
var minHeight = oLi[0].offsetHeight;
// 循环查找最短的li
for (var i = 0; i < oLi.length; i++) {
// 判断最短的li并赋值
if (minHeight > oLi[i].offsetHeight) {
minHeight = oLi[i].offsetHeight;
minIndex = i;
}
}
return {
minIndex: minIndex,
minHeight: minHeight,
}
}
getData();
// 滑轮滚动事件
window.onscroll = function (e) {
var scrollTop = document.documentElement.scrollTop;
var clientHeight = document.documentElement.clientHeight;
var minHeight = getMinLi().minHeight;
// 当滑轮滚动的距离+页面的高度比最短列大时获取数据
if (minHeight < scrollTop + clientHeight) {
if (!flag) {
page ++;
getData();
}
}
}
./image
0.png
1.png
2.png
3.png