zoukankan      html  css  js  c++  java
  • 瀑布流布局+无限滚动

    瀑布流:列对齐方式布局

    无限滚动:到底触发事件,获取内容更新至页面

    实现:

    通过web api里的IntersectionObserver,某标签出现在浏览器视口,就触发回调,瀑布流通过手动设置图片位置。

    IntersectionObserver参考文档:

    https://wangdoc.com/webapi/intersectionObserver.html#%E6%83%B0%E6%80%A7%E5%8A%A0%E8%BD%BD%EF%BC%88lazy-load%EF%BC%89

    实现代码:

    <!DOCTYPE html>
    <html lang="en">
    
    <head>
      <meta charset="UTF-8">
      <meta http-equiv="X-UA-Compatible" content="IE=edge">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <title>Document</title>
      <style>
        body {
          padding: 0;
          margin: 0;
        }
    
        .container {
          position: relative;
        }
    
        .container>div {
          position: absolute;
          display: flex;
          justify-content: center;
          align-items: center;
        }
    
        .container>div img {
          width: calc(100% - 0.5em);
          margin: 0.2em;
        }
      </style>
    </head>
    
    <body>
    
      <div style="height: 2em;display: flex;justify-content: center;align-items: center;">
        头部
      </div>
    
      <div class="container">
    
      </div>
    
      <div id="bottom" style="height: 2em;display: flex;justify-content: center;align-items: center;">
        底部
      </div>
    
      <script>
    
        // 获取随机整数
        function getRandomInt(min, max) {
          return Math.floor(Math.random() * (max - min + 1)) + min;
        }
    
        // 随机图片列表(测试用)
        let imgs = [
          "https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fgss0.baidu.com%2F7Po3dSag_xI4khGko9WTAnF6hhy%2Fzhidao%2Fpic%2Fitem%2F30adcbef76094b364b18a31ca2cc7cd98c109dbd.jpg&refer=http%3A%2F%2Fgss0.baidu.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1626869559&t=27bf6e2ea4f853fdcb30f8a3f3068981",
          "https://gimg2.baidu.com/image_search/src=http%3A%2F%2Finews.gtimg.com%2Fnewsapp_bt%2F0%2F13584429185%2F1000&refer=http%3A%2F%2Finews.gtimg.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1626869720&t=606d140718cd1def9e8ec81c3a1b8d5f",
          "https://gimg2.baidu.com/image_search/src=http%3A%2F%2Ftu1.whhost.net%2Fuploads%2F20181207%2F10%2F1544150166-YIVJLsFmDK.jpg&refer=http%3A%2F%2Ftu1.whhost.net&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1626869720&t=6a417c65f0732b4e2a8ed3d0071f1608",
          "https://ss0.bdstatic.com/70cFuHSh_Q1YnxGkpoWK1HF6hhy/it/u=291238033,2983030545&fm=26&gp=0.jpg",
          "https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fgss0.baidu.com%2F7Po3dSag_xI4khGko9WTAnF6hhy%2Fzhidao%2Fpic%2Fitem%2F3ac79f3df8dcd100adaf61ec728b4710b8122fcf.jpg&refer=http%3A%2F%2Fgss0.baidu.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1626870982&t=070f2f6f50e363fb3499711334b85d16",
          "https://ss0.baidu.com/94o3dSag_xI4khGko9WTAnF6hhy/zhidao/pic/item/3801213fb80e7bec8c1d93942d2eb9389a506b84.jpg",
        ]
    
        // 瀑布流高度列表,每次都在最低列上
        let heights = []
        // 瀑布流列数
        let coloum = 5
    
        // 观察器,监测底部元素,快到那里就添加元素
        let observer = new IntersectionObserver((entries, observer) => {
          // 底部只会有一个,所以这样写了
          let entrie = entries[0]
          let ratio = entrie.intersectionRatio
          console.log(`漏出${parseInt(ratio * 100)}%`, entries);
          // 获取图片
          if (ratio >= 0.2 && ratio <= 1) {
            // 获取图片数据
    
            // 添加元素,每次随机搞了15个(图片少可能触发不了,由图片高度决定,3行一般是肯定能)
            for (let i = 0; i < 15; i++) {
              let container_div = document.getElementsByClassName("container")[0]
              let div_img = document.createElement("div")
              let img = document.createElement("img")
              // 由于需要更方便的设置内边距所以图片外套了一个div
              div_img.style.width = `calc(${100 / coloum - 0.2}%)`
              div_img.append(img)
              // 设置图片路径,添加dom
              img.src = imgs[getRandomInt(0, imgs.length - 1)]
              container_div.appendChild(div_img)
              // 图片加载成功就需要设置位置,不在加载成功搞div撑不起来
              img.onload = () => {
                // 判断是否是第一行
                if (heights.length < coloum) {
                  div_img.style.top = 0
                  div_img.style.left = `${div_img.offsetWidth * heights.length}px`
                  heights.push(div_img.offsetHeight)
                } else {
                  // 找最低一列索引,每次都在最低列下面
                  let index = heights.indexOf(Math.min(...heights))
                  div_img.style.top = `${heights[index]}px`
                  div_img.style.left = `${div_img.offsetWidth * index}px`
                  heights[index] += div_img.offsetHeight
                }
                // 手动设置容器高度
                let max_height = Math.max(...heights)
                container_div.style.height = `${max_height}px`
              }
            }
            // 获取不到图片,关闭观察器
            if (document.getElementsByTagName("img").length >= 45) {
              observer.disconnect()
            }
          }
        }, { threshold: [0.2] })
    
        // 底部标签漏出5分之1就加载图片
        observer.observe(document.getElementById("bottom"))
    
      </script>
    
    </body>
    
    </html>

    效果图:

  • 相关阅读:
    求职简历撰写要点和模板分享
    find命令
    MD5Init-MD5Update-MD5Final
    Linux find命令详解
    Linux进程KILL不掉的原因
    Linux操作系统的内存使用方法详细解析
    Lsof命令详解
    为什么ps中CPU占用率会有超出%100的现象?
    第12课 经典问题解析一
    第11课 新型的类型转换
  • 原文地址:https://www.cnblogs.com/zezhou/p/14922797.html
Copyright © 2011-2022 走看看