ajax瀑布流的实现

假如我们是要将所有的图片内容分成3列,实现定宽的按需加载

瀑布流实现思路:

1、布局完成之后,用ajax请求相应的图片数据,
2、考虑到图片的长度不一,在渲染的时候,先判断一个每个列中那列是最短的,
3、找到最短的列之后,将图片渲染进来即可

瀑布流实现可能遇到的问题:

1、在判断最短列的时候,可能会用到for循环,由于图片请求是异步,循环不会等异步结束之后再走,所以会出现判断出最短列的时候,将图片渲染上,在还没有拿到图片的时候,没有高度,下一次循环依然将这列判断为最短的,下一张图片依然在这列渲染,之后前面的图片获取完成之后,就会出现问题

解决方案:
1、 使用递归,和图片的预加载结合实现
2、后端给我们提供图片的宽高值,我们直接给图片设置好宽高,这样在数据请求到之前就可以将高度撑开

如果是我们定宽,比如是200px,但是后端传给我们的宽度可能是其他的数值,这之后我们就直接用我们设置好的固定值200px就好
高度 = 后端提供的高度 * (200/后端给的宽度,这样就可以解决图片由于定宽而产生拉伸的问题

瀑布流案例:

<!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>ajax按需加载</title>
    <link rel="shortcut icon" href="#" />
    <style>
        body,p,h2{
            margin: 0;
        }
        img{
            vertical-align: top;
        }
        .list{
            margin: 0;
            padding: 0;
            list-style: none;
            font: 18px/30px "宋体";
        }
        .list li{
            width: 400px;
            float: left;
            margin: 10px;
        }
        .list .pic{
            margin-bottom: 40px;
        }
        .list .pic img{
            width: 400px;
        }
        .list .title{
            font-weight: normal;
            background: #eee;
        }
    
    </style>
</head>
<body>
    <ul class="list">
        <li></li>
        <li></li>
        <li></li>
    </ul>


<script>
    
var list = document.querySelector('.list');
let item = document.querySelectorAll('.list li');
let page = 1; //获取的页码,默认获取第一页的内容
let off = true;  //设置请求开关,以免发起过多的请求

getlist();  //初始化

window.onscroll =function(){
   var shortId = shortList()
   var scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
   lastOne = item[shortId]

   if(getTop(lastOne) < document.documentElement.clientHeight + scrollTop){
       if(off){
           off = false;
           page++;
           getlist();
       }
   }
}

function getlist(){
    ajax({
        url:'getPics.php',
        data:{cpage:page},
        fn:function(data){
        var data = JSON.parse(data);
        console.log(data)
        if(!data.length){
            return;
        }
        
        //创建html结构,之前是想着直接用模板字符串来创建结构,然后出现了一些问题,发现还是这样更加好处
        for(var i=0; i<data.length; i++){   
            var picHeight = (data[i]).height;
            var picWidth = (data[i]).width;
            var shortId = shortList()

            var pic = document.createElement('div');
            pic.classList.add('pic')

            var img = document.createElement('img')
            img.src = data[i].image;
            img.style.height = picHeight * (300/picWidth) +'px'
            img.classList.add('img')
            pic.appendChild(img);

            var title = document.createElement('p')
            title.classList.add('title')
            title.innerText = data[i].title
            pic.appendChild(title)

            item[shortId].appendChild(pic)

        }
                
        off = true;
    }})
}

function shortList(){   //获得最短列
    let aLi = document.querySelectorAll('.list li');
    let index = 0;
    let height = aLi[index].offsetHeight;
    for(let i=0; i<aLi.length; i++){
        if(aLi[i].offsetHeight < height){
            index = i
            height = aLi[i].offsetHeight
        }
    }
    return index;
}

function getTop(obj){
    let top = 0;
    if(obj){
        top += obj.offsetTop;
        obj = obj.offsetParent;
    }
    return top;
}


//-------------------------- ajax函数封装 ---------------------
 function ajax(init){
     let option = {  //设置一些参数默认值
         method: 'GET',
         data:{},
         async:true
     }
    let xhr = null;
    //声明一个Http请求,并且做IE的兼容,如果是用的if判断的话,可以判断window.XMLHttpRequest是否存在
    try{    
        xhr = new XMLHttpRequest();
    }catch(e){
        xhr = new ActiveXObject('Microsoft.XMLHTTP');
    }

    for(let a in init){
        option[a] = init[a];
    }
    //将请求数据方式字母都转化为大写字母
    option.method = option.method.toUpperCase();

    //对get方式进行处理
    if(option.method == 'GET'){
        option.url+= '?'+ dealData(option.data);
        xhr.open('GET',option.url,true)
        xhr.send();
    }
    else if (option.method == 'Post'){
        xhr.open('Post',option.url,true);
        xhr.setRequestHeader('content-type','application/x-www-form-urlencoded')
        xrh.send(dealData(option.data));
    }

    xhr.onreadystatechange = function(){
        if(xhr.readyState==4){
            if(xhr.status==200){
                option.fn && option.fn(xhr.responseText);
            }else{
                alert('出错了,Err:'+ xhr.status);
            }
        }
    }

    function dealData(data){
        let arr = []
        for(let i in data){
            arr.push(encodeURI(i) + "="+encodeURI(data[i]));
        }
        return arr.join('&');
    }

}
 
    
</script>
</body>
</html>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值