js实现动态加载数据瀑布流

Ula ·
更新时间:2024-09-20
· 720 次阅读

本文实例为大家分享了js实现动态加载数据瀑布流的具体代码,供大家参考,具体内容如下

实现的功能

1.每次下拉到底部会自动加载下一页的数据
2.图片逐渐显示

首先html

<!DOCTYPE html> <html lang="zh-CN">     <head>         <meta charset="UTF-8" />         <meta name="viewport" content="width=device-width, initial-scale=1.0" />         <title>Document</title>         <style>             * {                 margin: 0;                 padding: 0;             }             #wapper {                 width: 1200px;                 margin: 0 auto;                 position: relative;             }             .wr_item {                 position: absolute;                 overflow: hidden;             }             img {                 display: block;                 width: 100%;                 opacity: 0;                 transition: opacity 3s;             }         </style>     </head>     <body>         <div id="wapper"></div>         <script src="./scroll.js"></script>         <script src="./data.js"></script>         <script src="./warpper.js"></script>         <script type="text/javascript">             new Wapper({                 el: "wapper",                 el_itemClassName: "wr_item",                 colum: 8,                 gap: 10,             }).init();         </script>     </body> </html>

接着是主要的js

; (function (doc) {   // console.log('list', list);   var Wapper = function (op) {     this.el = doc.getElementById(op.el)     this.el_itemClassName = op.el_itemClassName     this.colum = op.colum     this.gap = op.gap     // 1.首先获取到每个照片外层盒子 也就是wr_item 的宽度     this.wr_item_w = (this.el.offsetWidth - (this.colum - 1) * this.gap) / this.colum     this.pageNum = 0     this.hightArr = []     this.pageSize = 4   }   Wapper.prototype = {     init() {       this.bindEvetn()       this.getData()     },     getData() {       // 这里默认一次获取30个照片 ,我这里了是假数据所以就不做别的了       // 一般这里是向后端请求数据       // list一共是有120       const partList = getPartList(this.pageNum)       if (partList) {         this.render(partList)         return true       } else {         return false       }     },     render(partList) {       // 只有数据存在才进行下面的操作       if (partList) {         partList.forEach((li, index) => {           const o_item = document.createElement('div')           // 这里要给o_item设置高度           // 不要想着用img撑开,这样做会导致不能够获取到o_item的offsetWidth           // 注意dom添加一个节点后,你是不能马上获取到其一些宽高的,           // 所以后端在返回数据的时候要给出高度           const imgW = li.width           const imgH = li.height           o_item.style.width = this.wr_item_w + 'px'           // 高度等于 盒子宽度x图片高度/图片宽度           const oitemH = (this.wr_item_w * imgH) / imgW           o_item.style.height = oitemH + 'px'           o_item.className = this.el_itemClassName           const img = new Image()           img.src = li.thumbURL           // 注意这里好像不能直接设置透明度,最好加个定时器触发重绘           // img.style.opacity = '1'           o_item.appendChild(img)           this.el.appendChild(o_item)           // 设置第一行            // 必须是第一页的数据           if (index < this.colum && this.pageNum === 0) {             this.hightArr.push(o_item.offsetHeight)             o_item.style.top = '0'             if (index + 1 % this.colum === 0) {               // 说明这是第一个               o_item.style.left = '0'             } else {               o_item.style.left = index * (this.wr_item_w + this.gap) + 'px'             }           } else {             const items = this.el.getElementsByClassName(this.el_itemClassName)             const minIndex = getMinIdx(this.hightArr)             const c_item = items[minIndex]             o_item.style.left = c_item.offsetLeft + 'px'             o_item.style.top = this.hightArr[minIndex] + this.gap + 'px'             this.hightArr[minIndex] += (o_item.offsetHeight + this.gap)           }           img.style.opacity = '1'         })         console.log('this.hightArr', this.hightArr);         this.el.style.height = this.hightArr[getMaxIdx(this.hightArr)] + 'px'       }     },     bindEvetn() {       var that = this       window.onscroll = function () {         if (getWindowHeight() + getScrollTop() === getHtmlScrollHeight()) {           console.log(that.pageNum);           that.pageNum++;           let hasNext = that.getData()           hasNext || that.pageNum--         }       }     }   }   function getPartList(pageNum) {     switch (pageNum) {       case 0:         return list.slice(0, 30)         break;       case 1:         return list.slice(30, 60)       case 2:         return list.slice(60, 90)       case 3:         return list.slice(90, 120)       default:         return null     }   }   // 找最小下标   function getMinIdx(arr) {     const minHeight = Math.min.apply(null, arr)     return [].indexOf.call(arr, minHeight)   }   // 找最大   function getMaxIdx(arr) {     const maxHeight = Math.max.apply(null, arr)     return [].indexOf.call(arr, maxHeight)   }   window.Wapper = Wapper })(document)

getWindowHeight() + getScrollTop() 是来检测浏览是不是滚动到底部的。

1.这里要注意几点 就是 后端给的数据 除了img的地址 还要给出每个img的宽高

2.在设置过渡 也就是我这里面的opacity:1的时候 要么在这之前触发回流操作 比如我这里有获取offsetHeight ,要么用一个定时器包括,否则这个过渡是不会生效的,图片会直接显示

3.后端每次返回的数据最好够多,否则会导致可能第一页数据不够多,导致没有出现滚动条 触发不了事件,当然最好是能自己写逻辑判断,后面有时间会完善这个代码,比如请求的选项也写到op里面,让用户手动传入

主要是大家理解这思路就好。



js实现 数据 瀑布 瀑布流 动态 js

需要 登录 后方可回复, 如果你还没有账号请 注册新账号