zoukankan      html  css  js  c++  java
  • 原生js实现图片瀑布流布局,注释超详细

    先看第一种方法

    代码:

    <!DOCTYPE html>
    <html lang="en">
    <head>
    <meta charset="UTF-8">
    <title>Title</title>
    </head>
    <style>
    * {
    margin: 0;
    padding: 0;
    }

    main {
    display: flex;
    align-items: flex-start;
    }

    div {
    margin: 5px;
    25%;
    }

    img {
    margin: 5px;
    100%;
    display: block;
    }
    </style>
    <body>
    <main>
    <div></div>
    <div></div>
    <div></div>
    <div></div>
    </main>
    <script>
    fetch('http://rap2.taobao.org:38080/app/mock/256901/json')
    .then(res => {
    return res.json();
    })
    .then(data => {
    let lis = document.querySelectorAll('div');
    let hh = [0,0,0,0] //存取4个div的高度
    let li = '';
    data.img.forEach(function(item) {
    let height = item.src.substring(item.src.indexOf('x')+1);//获取高度
    let str = `<img src="${item.src}" style="height:${height}px" />`;
    let minHeight = Math.min(...hh)//求最小高度
    let minIndex = hh.indexOf(minHeight)//求最小索引
    li = lis[minIndex];
    li.innerHTML += str;//给最小高度
    hh[minIndex]+=li.children[li.children.length-1].offsetHeight //更新最小高度
    })
    })
    </script>
    </body>
    </html>

    复制上面代码到浏览器解析运行,即可浏览效果

    第二种方法代码量会比上面多一些

    代码:

    <!DOCTYPE html>
    <html lang="en">
        <head>
            <meta charset="UTF-8">
            <meta name="viewport" content="width=device-width, initial-scale=1.0">
            <title>瀑布流</title>
            <style type="text/css">
                img {
                     300px;
    
                }
    
                li {
                    position: absolute;
                    s left: 0;
                    top: 0;
                    list-style: none;
                }
    
                ul {
                    margin: 0 auto;
                    position: relative;
                }
    
                * {
                    margin: 0;
                    padding: 0;
                }
            </style>
        </head>
        <body>
            <ul></ul>
        </body>
        <script src="utils.js"></script>
        <script>
            let ul = document.querySelector('ul'), //获取ul标签
                list = ul.children, //动态更新ul里面的子元素
                teep = 10, //间距
                width = 300, //每张图片的宽度
                cols = Math.floor(document.documentElement.clientWidth / (width + teep)), //计算有多少列
                hh = [], //存取每一列的高度
                num = 0, //记录加载完成图片数量
                om = 0 //记录已经排版完成的li数量
            ul.style.width = cols * (width + teep) - teep + 'px' //计算ul的宽度
            get({ //提前封装好的方法
                    url: 'http://rap2.taobao.org:38080/app/mock/256901/json'
                })
                .then(a => { //请求数据成功
                    a = JSON.parse(a).img
                    let dom = document.createDocumentFragment() //创建文档碎片
                    a.forEach((item, index) => { //有多少条数据就创建多少个li
                        let li = document.createElement('li')
                        li.innerHTML = `<img src="${item.src}">`
                        dom.appendChild(li) //把li添加到文档碎片中
                    })
                    ul.appendChild(dom) //将文档碎片添加到ul中
                    let imgs = Array.from(list).reduce((curr, item, index) => { //将每张img节点组成数组
                        if (om <= index) {
                            curr.push(item.querySelector('img'))
                        }
                        return curr
                    }, [])
    
                    Array.from(imgs).forEach(item => { //遍历每张图片
                        item.onload = () => { //该图片加载完成
                            num++
                            if (num === imgs.length) { //图片都加载完成了
                                for (let i = om; i < list.length; i++) { //遍历ul下的每个li
                                    if (i < cols) { //给第一行每个li设置left/top值
                                        list[i].style.left = (width + teep) * i + 'px'
                                        list[i].style.top = teep + 'px'
                                        hh.push(list[i].offsetHeight + teep * 2)
                                    } else { //除了第一行剩下的li
                                        let minHeight = Math.min(...hh) //求出最小高度
                                        let minIndex = hh.indexOf(minHeight) //求出最小高度的索引值
                                        list[i].style.left = (width + teep) * minIndex + 'px'
                                        list[i].style.top = minHeight + 'px'
                                        hh[minIndex] = list[i].offsetHeight + minHeight + teep //将最小高度更新
                                    }
                                }
                                om = list.length //更新排版完成数量
                                ul.style.height = ul.scrollHeight + 'px' //给ul设置高度
                            }
                        }
                    })
                })
        </script>
    </html>

    复制以上代码,并把下面这一段js代码复制到js文件中放到和上面代码同级的地方并引入,即可运行浏览效果

    代码如下:

    function ajax(obj, fn) {
        let ajx = new XMLHttpRequest() //创建ajax实例
        obj.type = obj.type ? obj.type : 'get' //判断type存不存在,不存在默认等于get
        let data = '' //向后端发送的数据
        if (obj.data) { //判断是否存在
            for (let i in obj.data) {
                data += i + '=' + obj.data[i] + '&' //键值拼接成name=zhagnsan&age=18形式
            }
            let k = data.split('')
            k.splice(data.length - 1, 1)
            data = k.join('')
        }
        if (obj.type == 'get') { //处理get请求发送数据
            ajx.open(obj.type, obj.url + '?' + data) //地址上拼接数据
            ajx.send()
        } else if (obj.type == 'post') { //处理post请求发送数据
            ajx.open(obj.type, obj.url)
            ajx.setRequestHeader('content-type', 'application/x-www-form-urlencoded') //设置请求头
            ajx.send(data) //发送数据
        }
        ajx.onreadystatechange = () => {
            if (ajx.readyState == 4) {
                if (ajx.status == 200) {
                    /*
                    将得到的数据传给回调函数
                    短路写法,如果不传fn为空不会执行,有值就执行
                    */
                    fn && fn(ajx.responseText)
                }
            }
        }
    }
    
    // ajax({ //调用封装的方法
    //     type: 'get', //可以不写,默认get
    //     url: 'http://localhost/day02/api/gouwu.php', //请求地址
    //     data: { //需要传输的数据,可选
    //         name: 'zhangsan',
    //         age: 18
    //     }
    // },a=>{//处理的到的数据
    //     console.log(a)
    // })
    
    function jsonp(obj) {
        let sc = document.createElement('script')
        let data = ''
        if (obj.data) {
            for (let i in obj.data) {
                data += `${i}=${obj.data[i]}&`
            }
            data = data.slice(0, -1)
            sc.setAttribute('src', obj.url + `?cd=${obj.cd}&${data}`)
        } else {
            sc.setAttribute('src', obj.url + `?cd=${obj.cd}`)
        }
    
        document.body.appendChild(sc)
    }
    
    // jsonp({
    //     url:'http://localhost/day02/api/gouwu.php',
    //     cd:'fn'
    // },a=>{
    //     console.log(a)
    // })
    
    function get(obj) {
        return new Promise((resolve, reject) => {
            let a = new XMLHttpRequest()
            let data = ''
            if (obj.data) {
                for (let i in obj.data) {
                    data += i + '=' + obj.data[i] + '&'
                }
                data = data.slice(0, -1)
                a.open('get', obj.url + '?' + data)
            }else{
                a.open('get', obj.url)
            }
            a.send()
            a.onreadystatechange = () => {
                if (a.readyState === 4) {
                    if (a.status === 200) {
                        resolve(a.responseText)
                    } else {
                        reject()
                    }
                }
            }
        })
    
    }
    // get({//调用格式
    //     url:'http://localhost/day02/api/gouwu.php',//获取的地址
    //     data:{ //可不写
    //         a:1,
    //         b:2
    //     }
    // }).then(a=>{//获取数据成功
    //     console.log(a)
    // }).catch(err=>{ //获取数据失败
    //     console.log(err)
    // })
  • 相关阅读:
    2018.10.11----2018.10.13 计算机网络(写了两天)
    2018.10.10 Java的The superclass "javax.servlet.http.HttpServlet" was not found on the Java Build Path 错误
    2018.10.10 MAC 的Launchpad图标改变大小的设置
    2018.10.8 Hibernate中解决乱码问题---配置一个过滤器
    2018.10.7 理解Hibernate的工作原理及其中的ORM详解
    2018.10.6 Hibernate配置文件详解-------ORM元数据配置 &&& hibernate主配置文件
    2018.10.5 hibernate导入约束,在Eclipse的xml文件实现自动提示
    2018.10.4 AndroidStudio
    2018.10.3 MianShiBaoDian JavaWeb后端部分
    C语言练习之 冒泡排序(二)
  • 原文地址:https://www.cnblogs.com/zlf1914/p/13068143.html
Copyright © 2011-2022 走看看