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

本文实例为大家分享了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里面,让用户手动传入

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

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • JavaScript实现瀑布流以及加载效果

    一.瀑布流是个啥? 瀑布流,是比较流行的一种网站页面布局,视觉表现为参差不齐的多栏布局,随着页面滚动条向下滚动,这种布局还会不断加载数据块并附加至当前尾部. 最早采用瀑布流布局的网站是Pinterest,逐渐在国内流行开来,比如我们熟知的百度图片的布局,在"很久"以前,百度图片还是需要一页一页的点击进行查看更多图片,而现在的瀑布流布局使用户查找图片更加方便. 二.瀑布流的优缺点 优点: 1.节省了页面的空间,不再需要导航和页码按钮. 2.增强了用户的体验,使用户的体验更多的是在于浏览图

  • javascript实现瀑布流动态加载图片原理

    本文实例为大家分享了js瀑布流加载效果,动态加载图片,供大家参考,具体内容如下 鼠标滚动事件,当鼠标滚动到下边,动态加载图片. 1. HTML代码     <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>js实现瀑布流效果-动态加载图片</title> <link rel="stylesheet" href="

  • javascript实现瀑布流加载图片原理

    讲一下大概的原理吧,还是先上图:  功能描述: 根据不同菜单的属性值分别加载不同的数据 下拉滚动条到一定位置预加载图片,滚动条拉到最底下的时候渲染html: 鼠标移到菜单,切换各个图片列表: 鼠标移到图片列表上,显示详细信息:  技术实现方案: 先梳理一下从加载到显示的流程: 1. 加载数据 2. 拼接HTML写入到页面 3. 检查刚刚写入的HTML中的img是否全部加载完成,如果是,进入5.否则进入4 4. 等待图片加载完成 5. 计算每个元素的位置 一开始的时候最头疼的是如何定位的问题,后来

  • 利用JS实现简单的瀑布流加载图片效果

    今天学习了一个瀑布流加载效果,很多网站都有瀑布流效果,瀑布流就是很多产品显示在网页上,宽相同,高度不同,表现为多栏布局,随着页面滚动条向下滚动,这种布局还会不断加载数据块并附加至当前尾部. 原理是: 1.设定一行中的列数: 2.取第一行中每一个div的高度并把每一个高度放进一个数组中: 3.算出数组中最小高度的index值: 4.把第二行的第一个div放到最小高度的div的下方并把重新算出的高度值放进数组中,重新计算最小高度的index值: 5.以此类推实现多栏布局的瀑布流效果: 6.如果最后一

  • javascript瀑布流式图片懒加载实例解析与优化

    之前写过一版图片"懒加载"的文章,刚好周末在整理文件的时候,大概又看了一遍之前写的代码发现有很多可以优化的地方. 这篇文章主要就是结合上篇<javascript瀑布流式图片懒加载实例>再来看看图片"懒加载"的一些知识. 图片"懒加载"的主旨: 按照需要加载图片,也就是说需要显示的时候再加载图片显示,减少一次性加载的网络带宽开销. 先来看一段代码: var conf = { 'loadfirst': true, 'loadimg': t

  • 解析javascript瀑布流原理实现图片滚动加载

    先科普下瀑布流吧 瀑布流,又称瀑布流式布局.是比较流行的一种网站页面布局,视觉表现为参差不齐的多栏布局,随着页面滚动条向下滚动,这种布局还会不断加载数据块并附加至当前尾部.最早采用此布局的网站是Pinterest,逐渐在国内流行开来.国内大多数清新站基本为这类风格,像美丽说.淘宝网都有使用. 这是我实现的一个效果,就是怎么滚动都加载不玩.就跟瀑布一样流啊流! 这里的实现方式我们只说Js实现方法 实现原理: 对容器中已有数据块元素进行第一次计算1 容器总宽度 2 列宽度  3 最小列数 ,得到列数

  • javascript瀑布流式图片懒加载实例

    最近项目使用到了"懒加载",现在更新一般,因为平时主要使移动端的开发所以库文件使用的是zepto.js .当然也可以和jQuery 通用. 代码如下: /** * Created by zhiqiang on 2015/10/14. * hpuhouzhiqiang@gmail.com * 图片的懒加载 **/ function loadImgLazy(node) { var lazyNode = $('[node-type=imglazy]', node), mobileHeight

  • JavaScript实现图片自动加载的瀑布流效果

    先给大家展示下效果图: 向下滑动网页的时候能够自动加载图片并显示. 盛放图片的盒子模型如下: <div class="box"> <div class="box_img"> <img src="Img/8.jpg"> </div> </div> 设置img-width为150px,然后box_img添加内边距和阴影效果,box的外边距为0,添加内边距.盒子的宽度是由img-width和边

  • js图片加载效果实例代码(延迟加载+瀑布流加载)

    主要做了两种图片加载的效果 一种是遇到页面图片比较多的时候,带读条效果的加载提示(为了验证正确加载,设置了1秒钟的加载间隔时间) 另外一种是根据滑块的位置进行图片的预加载,在用户不察觉的情况下,实现瀑布流的加载效果 一 延迟加载 主要思路: HTML的img标签中,将正确的地址存在data-src属性中,给所有图片设置一个转圈圈的loading图片作为background js中,依次读取每一个img,将data-src中的地址替换到src中,去掉background 每成功加载一张图片,进度条

  • javascript实现仿百度图片的瀑布流加载效果

    由于没有服务器,就用一个json字符串作为下拉时加载图片数据的来源了 html: <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <script src="js/waterfall.js"></script> <styl

随机推荐