ajax获取图片数据,实现瀑布流功能

289 阅读4分钟

项目github地址

封装 AJAX

// ajax: async javascript and xml (json) "{}"
//        异步的JavaScript 和 xml(json)
//        同步:一行一行  (按顺序执行)
//        异步:同时进行的
//        用途: 数据交互


// 用 问问题来举例  类比  网络请求
// 问问题:
// 问的问题内容:   --->    请求参数
// 问的是谁:       --->    接口
// 通过什么方式去问  --->    请求方式
// 说话的方式       --->    请求头
// 收到数据做什么处理 --->   作为一个成功的回调函数


/**
*  @params {Object} options
            method  请求方式
            url     请求地址
            isAsync 是否异步
            data        请求参数(发送的数据)
            success   拿到数据之后的回调函数
*/

function AJAX(options) {
    var method = options.method.toUpperCase();
    var url = options.url;
    var isAsync = options.isAsync;
    var data = options.data;
    var dataStr = '';
    var success = options.success || function() {};
    var xhr = null;


    if (window.XMLHttpRequest) {
        xhr = new XMLHttpRequest();
    } else if (window.ActiveXObject) {
        xhr = new ActiveXObject('Microsoft.XMLHTTP');
        // 兼容性写法,兼容IE6 以下, 括号内的参数 是 固定参数
    } else {
        return alert('当前浏览器不支持XMLHTTPRequest');
    }

    // 判断传递过来的数据是否是对象类型的  如果是对象类型的转换成字符串  key=value&key1=value1
    if (typeof data === 'object') {
        for (var prop in data) {
            if (data.hasOwnProperty(prop)) {
                dataStr += prop + '=' + data[prop] + '&';
            }
        }
    } else {
        dataStr = data.toString();
    }

    // 监听readyState属性的变化   readyState属性是用来记录当前数据交互的过程状态的
    // readyState的值 0 - 4   
    // 0 代表还没有进行数据交互  
    // 1 代表还没有建立连接     (open方法还没有执行) 
    // 2 代表连接已经建立了     (open方法已经执行)
    // 3 代表数据传递完成       (send方法执行完成)
    // 4 代表对方已经给了响应 

    xhr.onreadystatechange = function() {
        // console.log(xhr.readyState)
        if (xhr.readyState === 4) {
            // xhr.status
            if (xhr.status === 200) {
                success(JSON.parse(xhr.responseText))
            }
        }
    }

    // 将请求方式全部转换成大写
    var method = options.method.toUpperCase();
    // 判断请求方式为get类型   GET类型的特点:数据拼接在地址当中
    if (method === 'GET') {
        // 建立连接
        xhr.open(method, url + '?' + dataStr, isAsync);
        // 发送数据
        xhr.send();
    } else {
        // 请求方式为非get请求的   那么需要单独传递请求参数(数据) 就需要告诉对方你的数据编码方式(通过请求头设置) 
        xhr.open(method, url, isAsync);
        // key=value&key1=value1&key2=value2.....   ContentType 代表的是编码方式  
        //     "{key: value, key1: value1}"         application/json
        //     传入两个参数  第一个 是 请求头要的名字   
        xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
        xhr.send(dataStr);
    }

}

HTML结构

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

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>AJAX 获取图片数据 实现瀑布流操作</title>
    <link rel="stylesheet" href="index.css">
</head>

<body>
    <ul class="wrapper">
        <li class="col"></li>
        <li class="col"></li>
        <li class="col"></li>
        <li class="col"></li>
    </ul>

    <script src="JS/ajax.js"></script>
    <script src="JS/index.js"></script>
</body>

</html>

index.css

* {
    margin: 0;
    padding: 0;
}

.wrapper {
    width: 980px;
    margin: 0 auto;
    list-style: none;
    background-color: #eee;
}

.wrapper li {
    float: left;
    width: 25%;
}

.wrapper li::after {
    content: '';
    display: block;
    clear: both;
}

.wrapper::after {
    content: '';
    display: block;
    clear: both;
}

.wrapper .col div {
    margin: 10px;
    padding: 10px;
    background-color: #fff;
}

.wrapper .col div img {
    width: 100%;
}

index.js

function getData() {
    AJAX({
        method: 'GET',
        url: '../data.json',
        isAsync: true,
        data: '',
        success: function(data) {
            console.log(data);
            renderDom(data);
        }
    })
}

var oLi = document.getElementsByClassName('col');

function renderDom(data) {
    data.forEach(function(item) {
        var itemDom = createPic(item);
        // oLi[index % 4].appendChild(itemDom);
        var index = getMinLi().minIndex;
        oLi[index].appendChild(itemDom);
    })
}
// 图片渲染宽度
var imgWidth = oLi[0].offsetWidth - 20 - 20;

// 创建图片结构的 
function createPic(data) {
    var oItem = document.createElement('div');
    oItem.className = 'item';
    var oImg = new Image();
    oImg.src = data.img;

    // 因为图片资源的加载是异步的,所以,加载还未完成,也就是说,高度还未计算好,我们就插入图片,这样的话就会一直从第一列开始插入
    // 预留img的高度
    // 图片本身的宽高比为  data.width / data.height
    // 渲染到页面当中图片的宽度: oLi[0].offsetWidth - 20 - 20   
    // 求渲染图片的高度: 
    // data.width       imgWidth
    // ---------    =   ----------
    // data.height        height

    oImg.height = imgWidth * data.height / data.width;
    var oP = document.createElement('p');
    oP.innerText = data.desc;
    oItem.appendChild(oImg);
    oItem.appendChild(oP);
    return oItem;
}

// 查找最短列
function getMinLi() {
    var oLi = document.getElementsByClassName('col');
    var minIndex = 0;
    var minHeight = oLi[minIndex].offsetHeight;
    for (var i = 0; i < oLi.length; i++) {
        if (oLi[i].offsetHeight < minHeight) {
            minHeight = oLi[i].offsetHeight;
            minIndex = i;
        }
    }
    return {
        minHeight: minHeight,
        minIndex: minIndex
    }
}

getData()

var timer = null;
window.onscroll = function() {
    var scrollYOffset = window.pageYOffset;
    var innerHeight = window.innerHeight;
    var minHeight = getMinLi().minHeight;
    clearTimeout(timer);
    // 判断页面当中是否出现空白  如果出现空白则获取下一组数据
    if (scrollYOffset + innerHeight > minHeight) {
        // 防抖处理
        timer = setTimeout(function() {
            getData();
        }, 500);
    }
}

// 懒加载:  用到的时候去加载
// 预加载:   先把所有资源全部拿到然后用的时候直接拿过来

data.json

[{
    "img": "image/0.png",
    "desc": "第1张小女孩图片",
    "height": 640,
    "width": 424
}, {
    "img": "image/1.jpg",
    "desc": "第2张小女孩图片",
    "height": 800,
    "width": 533
}, {
    "img": "image/2.jpg",
    "desc": "第3张小女孩图片",
    "height": 333,
    "width":500
},{
    "img": "image/3.jpg",
    "desc": "第4张小女孩图片",
    "height": 450,
    "width": 253

}, {
    "img": "image/4.jpg",
    "desc": "第5张小女孩图片",
    "height": 500,
    "width": 500
}, {
    "img": "image/5.jpg",
    "desc": "第6张小女孩图片",
    "height": 712,
    "width": 500 
    
},{
    "img": "image/6.jpg",
    "desc": "第7张小女孩图片",
    "height": 750,
    "width": 499
}, {
    "img": "image/7.jpg",
    "desc": "第8张小女孩图片",
    "height": 720,
    "width": 480
}, {
    "img": "image/8.jpg",
    "desc": "第9张小女孩图片",
    "height": 750,
    "width": 500
},{
    "img": "image/9.jpg",
    "desc": "第10张小女孩图片",
    "height": 500,
    "width": 500
}, {
    "img": "image/10.jpg",
    "desc": "第11张小女孩图片",
    "height": 432,
    "width": 288
}, {
    "img": "image/11.jpg",
    "desc": "第12张小女孩图片",
    "height": 650,
    "width": 447
},{
    "img": "image/12.jpg",
    "desc": "第13张小女孩图片",
    "height": 600,
    "width": 500
}, {
    "img": "image/13.jpg",
    "desc": "第14张小女孩图片",
    "height": 951,
    "width": 658
}, {
    "img": "image/14.jpg",
    "desc": "第15张小女孩图片",
    "height": 862,
    "width": 603
}, {
    "img": "image/15.jpg",
    "desc": "第16张小女孩图片",
    "height": 750,
    "width": 499
}]