UNPKG

zx-waterfall

Version:
205 lines (203 loc) 5.37 kB
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width,initial-scale=1"> <title>zx-waterfall demo by capricorncd</title> <style> * { margin: 0; padding: 0; } body { padding-top: 60px; } h2 { position: fixed; z-index: 10; top: 0; left: 0; width: 100%; height: 60px; line-height: 60px; background-color: rgba(0, 0, 0, 0.8); color: #ccc; text-align: center; } .container { position: relative; overflow-x: hidden; overflow-y: scroll; } .container .item { padding: 20px; box-sizing: border-box; background-color: #ccc; border-radius: 4px; overflow: hidden; } .container .item dt { padding-bottom: 10px; } .container .item dt i { padding-right: 10px; font-weight: bold; color: #c00; } .container .item img { width: 100%; height: auto; border-radius: 2px; } .loading { position: fixed; z-index: 9; top: 50%; left: 50%; margin: -60px 0 0 -100px; width: 200px; height: 120px; background-color: #fff; border-radius: 4px; box-shadow: 0 5px 10px rgba(0, 0, 0, 0.5); opacity: 0.9; display: flex; flex-direction: column; justify-content: center; align-items: center; } .loading i { position: relative; display: inline-block; width: 50px; height: 50px; box-sizing: border-box; border: 3px #c00 dashed; border-radius: 50%; animation: rotate 2s linear infinite; } .loading p { margin-top: 10px; } @keyframes rotate { form { transform: rotate(0); } to { transform: rotate(360deg); } } </style> </head> <body> <div id="app"> <h2>{{ title }}</h2> <div class="container" ref="container"> <dl class="item" v-for="(item, index) in list" :key="index" style="display: none;"> <dt><i>#{{ index + 1 }}</i>{{ item.content }}</dt> <dd> <img v-for="(media, i) in item.medias" :key="i" :src="media.thumb" alt=""> </dd> </dl> </div> <div v-show="isNotMore" style="text-align: center;color: red;">没有更多数据了</div> <div class="loading" v-show="loadState && !isNotMore"> <i></i> <p>loading ...</p> </div> </div> <script src="https://cdnjs.cloudflare.com/ajax/libs/js-polyfills/0.1.42/polyfill.min.js"></script> <!-- 生产环境版本,优化了尺寸和速度 --> <script src="https://cdn.jsdelivr.net/npm/vue"></script> <script src="./zx-waterfall.js"></script> <script src="./mock-json.js"></script> <script> // 模拟数据 var mockList = JSON.parse(mockJsonStr); var vm = new Vue({ beforeDestroy: function () { this.waterfall.destroy(); this.$container.removeEventListener('scroll', this.handleScroll); }, data: { title: 'zx-waterfall demo', // 列表数据 list: [], // 瀑布流实例 waterfall: null, // 数据请求页数 page: 1, // 每页数据条数 pageSize: 10, // 容器元素 $container: null, // 数据请求/加载状态 loadState: false, // 没有更多数据了 isNotMore: false }, el: '#app', methods: { getList: function () { // 判断数据是否已加载,或已无更多数据 if (this.loadState) return; this.loadState = true; // 模拟延时请求 var timer = setTimeout(function () { var list = mockList.slice((vm.page - 1) * vm.pageSize, vm.page * vm.pageSize); if (list.length) { vm.list = vm.list.concat(list); vm.page++; // 获取媒体(图片)元素 var medias = [] list.forEach(function (item) { item.medias.forEach(function (val) { medias.push(val.thumb); }) }) // 预加载图片 vm.waterfall.loadMedia(medias).then(function () { // 通知瀑布流,更新视图 vm.waterfall.update(); vm.loadState = false; vm.isNotMore = false; }) } else { vm.isNotMore = true; } clearTimeout(timer); }, 300) }, handleScroll: function () { var $el = this.$container; var scrollTop = $el.scrollTop var scrollHeight = $el.scrollHeight if (scrollHeight - scrollTop - $el.offsetHeight < 100) { vm.getList() } } }, mounted: function () { // 获取容器DOM元素 this.$container = this.$refs.container; // 设置容器高度, 窗口高度 - 头部header高度 - 底部预留20像素距离 this.$container.style.height = window.innerHeight - 60 - 20 + 'px'; // 实例化瀑布流 this.waterfall = new ZxWaterfall({ container: this.$container, itemSelector: '.item' }) // console.log(this.waterfall); // 获取数据 this.getList(); // 添加滚动事件监听 this.$container.addEventListener('scroll', this.handleScroll); } }) </script> </body> </html>