最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • 聊聊用JS实现网页瀑布流布局

    正文概述 掘金(范佐)   2021-04-18   525

    前言:

    瀑布流 又称瀑布流式布局,是比较流行的一种网站页面布局方式。即多行等宽元素排列,后面的元素依次添加到其后,等宽不等高,根据图片原比例缩放直至宽度达到我们的要求,依次按照规则放入指定位置。

    什么是瀑布流布局:

    先看效果:

    聊聊用JS实现网页瀑布流布局

    • 图片多行等宽元素排列,后面的元素依次添加到其后,等宽不等高,根据图片原比例缩放直至宽度达到我们的要求,依次按照规则放入指定位置。
    • 为了方便理解,在此先给上html、css代码

    不完整html代码:

    <div id="container">
            <div class="box">
                <div class="box-img">
                    <img src="./img/1.jpg" >
                </div>
            </div>
            <div class="box">
                <div class="box-img">
                    <img src="./img/2.jpg" >
                </div>
            </div>
            <div class="box">
                <div class="box-img">
                    <img src="./img/3.jpg" >
                </div>
            </div>
         </div>
         ......<!-- 省略了图片,多少张图片自行决定-->
    

    完整的css代码

    *{
            padding: 0;
            margin: 0;
        }
        #container{
            position: relative;
        }
        .box{
            float: left;
            padding: 15px;
        }
        .box-img {
            width: 150px;
            padding: 5px;
            border: 1px solid #ccc ;
            box-shadow: 0 0 5px #ccc;
            border-radius: 5px;
        }
        .box-img img{
            width: 100%;
            height: auto;
        }
    

    如何实现:

    简单地来说,如果要实现瀑布流布局,得完成这几件事✍

    1. 获取图片

    function getChildElemnt() {
        const contentArr = []//定义数组准备装图
        const parent = document.getElementById(container)//得到整个页面
        const allContent = parent.getElementsByTagName('*')//得到整个标签
        console.log(allContent);
        for (var i = 0; i < allContent.length; i++) {
          if (allContent[i].className == 'box') {
            contentArr.push(allContent[i])//将class='box'的标签装入数组
          }
        }
        console.log(contentArr);
        return contentArr//返回数组
     }
    

    2. 设置图片宽带

     var ccontent = getChildElemnt()
      var imgWidth = ccontent[0].offsetWidth//令所有图片宽度等于第一张图片
    

    3. 计算浏览器页面一行最多能存放图片的数量

    var dWidth=document.documentElement.clientWidth//页面宽度
    var num = Math.floor(dWidth/ imgWidth)
    //Math.floor()向下取整
    

    4. 比较图片高度

    • 因为在瀑布流布局中,当第一行图片已经摆满后,第二行的第一张图片要放在第一行中高度最小的图片的下面
    var BoxHeightArr = []//定义一个数组,把每张图片的高度依次放进去
        for (var i = 0; i < ccontent.length; i++) {
          if (i < num) {
            BoxHeightArr[i] = ccontent[i].offsetHeight//将图片的高度存入数组
          } else {//当第一行已经存放不了图片后
            var minHeight = Math.min.apply(null, BoxHeightArr)//比较出上一行最小的高度
            
          }
        }
    

    5. 得到上一行中最小高度图片的位置

    //定义一个getMinHeightLocation函数,给它传入BoxHeightArr上一行全部图片,和minHeight上一行图片的最小高度
      function getMinHeightLocation(BoxHeightArr, minHeight) {
        for (var i in BoxHeightArr) {
          if (BoxHeightArr[i] === minHeight) {//当图片高度等于最小高度时,该图片的位置为最小高度图片的位置
            return i
          }
        }
      }
    

    6. 插图

        for (var i = 0; i < ccontent.length; i++) {
        if (i < num) {
          BoxHeightArr[i] = ccontent[i].offsetHeight
        } else {
          var minHeight = Math.min.apply(null, BoxHeightArr)
          var minIndex = getMinHeightLocation(BoxHeightArr, minHeight)
          ccontent[i].style.position = 'absolute'//将要插入的图片绝对定位,即元素的位置通过 "left", "top", "right" 以及 "bottom" 属性进行规定
          ccontent[i].style.top = minHeight + 'px'//令插入的图片到顶端的距离刚好等于要插其下面图片的高度
          ccontent[i].style.left = ccontent[minIndex].offsetLeft + 'px'//令插入的图片到最左边的距离刚好等于要插其下面图片到最左边的距离
          BoxHeightArr[minIndex] = BoxHeightArr[minIndex] + ccontent[i].offsetHeight//插入图片后,得将这位置的高度设为两张图片的高度和
        }
      }
    

    完整代码如下:

    优化代码,提高性能

    window.onload = function() {
      imgLocation('container', 'box')//构造函数imgLocation
    }
    //用window.onload = function() {}函数就不用等着body页面中调用就可以执行了
    
    // 获取到当前有多少张图片要摆放
    function imgLocation(parent, content) {//令parent='container',content='box'
      // 将parent下所有的内容全部取出
      var cparent = document.getElementById(parent)
      var ccontent = getChildElemnt(cparent, content)
      var imgWidth = ccontent[0].offsetWidth
      var num = Math.floor(document.documentElement.clientWidth / imgWidth)
      cparent.style.cssText = `width: ${imgWidth * num} px`
    
      var BoxHeightArr = []
      for (var i = 0; i < ccontent.length; i++) {
        if (i < num) {
          BoxHeightArr[i] = ccontent[i].offsetHeight
        } else {
          var minHeight = Math.min.apply(null, BoxHeightArr)
          var minIndex = getMinHeightLocation(BoxHeightArr, minHeight)
          ccontent[i].style.position = 'absolute'
          ccontent[i].style.top = minHeight + 'px'
          ccontent[i].style.left = ccontent[minIndex].offsetLeft + 'px'
          BoxHeightArr[minIndex] = BoxHeightArr[minIndex] + ccontent[i].offsetHeight
        }
      }
      // console.log(BoxHeightArr);
    }
    
    
    function getChildElemnt(parent, content) {parent='container',content='box'
      const contentArr = []
      const allContent = parent.getElementsByTagName('*')
      console.log(allContent);
      for (var i = 0; i < allContent.length; i++) {
        if (allContent[i].className == content) {
          contentArr.push(allContent[i])
        }
      }
      console.log(contentArr);
      return contentArr
    }
    
    function getMinHeightLocation(BoxHeightArr, minHeight) {
      for (var i in BoxHeightArr) {
        if (BoxHeightArr[i] === minHeight) {
          return i
        }
      }
    }
    
    

    本人是在校大三学生,也是在边学习边总结,如果有写的不妥的地方,请大家评论指出???


    起源地下载网 » 聊聊用JS实现网页瀑布流布局

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元