基于JavaScript实现瀑布流布局


Posted in Javascript onAugust 15, 2018

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

1、html+css+js代码:

<!DOCTYPE html>
<html>
<head>
  <meta http-equiv="Content-Type" content="text/html" charset="utf-8" />
  <title>hhh</title>
</head>
<body>
  <style type="text/css">
    *{
      padding: 0;
      margin: 0;
    }
    #main{
      position: relative;
    }
    .pin{
      float: left;
      padding: 15px 0 0 15px;
    }
    .box{
      border-radius: 5px;
      box-shadow: 0 0 6px #ccc;
      border:1px solid #ccc;
      padding: 10px;

    }
    .box img{
      width: 162px;
      height:auto;
    }
  </style>

<script type="text/javascript">
  window.onload = function(){

    waterfall("main","pin");

    var dataint = {'data':[{'src':'1.jpg'},{'src':'2.jpg'},{'src':'3.jpg'},{'src':'4.jpg'}]};

    window.onscroll = function(){
      if (checkscrollside()) {
        var oparent = document.getElementById('main');
        for (var i = 0; i < dataint.data.length; i++) {
          var opin = document.createElement('div');
          opin.className = 'pin';
          oparent.appendChild(opin);
          var obox = document.createElement('div');
          obox.className = 'box';
          opin.appendChild(obox);
          var oimg = document.createElement('img');
          oimg.src = './images/' +dataint.data[i].src;
          obox.appendChild(oimg);
        }
        waterfall('main','pin');
      };
    }


  }

  //parent为父元素的id,pin为子元素id
  function waterfall(parent,pin){
    var oparent = document.getElementById(parent);
    var apin = getclassobj(oparent,pin);//获取id为oparent的类名为pin的元素
    var ipinw = apin[0].offsetWidth;
    var num = Math.floor(document.documentElement.clientWidth/ipinw);
    oparent.style.cssText = 'width:' + ipinw*num + 'px;margin:0 auto;';

    var pinharr = [];
    for( var i = 0;i < apin.length; i++)
    {
      var pinh = apin[i].offsetHeight;
      if (i < num) {
        pinharr[i] = pinh;
      }
      else{
        var minh = Math.min.apply(null,pinharr);
        var minhindex = getminhindex(pinharr,minh);
        apin[i].style.position = 'absolute';
        apin[i].style.top = minh +'px';
        apin[i].style.left = apin[minhindex].offsetLeft + 'px';
        pinharr[minhindex] += apin[i].offsetHeight; 
      }

    }
  }

  //获取id为parent的类名为classname的元素
  function getclassobj(parent,classname){

    var obj = parent.getElementsByTagName('*');
    var pins = [];
    for (var i = 0; i < obj.length; i++) {
      if (obj[i].className == classname) {
        pins.push(obj[i]);
      }
    };
    return pins;
  }

  function getminhindex(arr,minh){
    for(var i in arr){
      if (arr[i] == minh) {
        return i;
      }
    }
  }

  function checkscrollside(){
    var oparent = document.getElementById('main');
    var apin = getclassobj(oparent,'pin');
    var lastpinh = apin[apin.length - 1].offsetTop + Math.floor(apin[apin.length - 1].offsetHeight/2);
    var scrollTop = document.documentElement.scrollTop||document.body.scrollTop;
    var documenth = document.documentElement.clientHeight;
    return(lastpinh<scrollTop + documenth)?true:false;
  }
</script>
</body>
  <div id="main">
    <div class="pin">
      <div class="box">
        <img src="images/0.jpg">
      </div>
    </div>
    <div class="pin">
      <div class="box">
        <img src="images/1.jpg">
      </div>
    </div>
    <div class="pin">
      <div class="box">
        <img src="images/2.jpg">
      </div>
    </div>
    <div class="pin">
      <div class="box">
        <img src="images/3.jpg">
      </div>
    </div>
    <div class="pin">
      <div class="box">
        <img src="images/4.jpg">
      </div>
    </div>
    <div class="pin">
      <div class="box">
        <img src="images/5.jpg">
      </div>
    </div>
    <div class="pin">
      <div class="box">
        <img src="images/6.jpg">
      </div>
    </div>
    <div class="pin">
      <div class="box">
        <img src="images/7.jpg">
      </div>
    </div>
    <div class="pin">
      <div class="box">
        <img src="images/8.jpg">
      </div>
    </div>
    <div class="pin">
      <div class="box">
        <img src="images/9.jpg">
      </div>
    </div>
    <div class="pin">
      <div class="box">
        <img src="images/10.jpg">
      </div>
    </div>
    <div class="pin">
      <div class="box">
        <img src="images/11.jpg">
      </div>
    </div>
    <div class="pin">
      <div class="box">
        <img src="images/12.jpg">
      </div>
    </div>
    <div class="pin">
      <div class="box">
        <img src="images/13.jpg">
      </div>
    </div>
    <div class="pin">
      <div class="box">
        <img src="images/14.jpg">
      </div>
    </div>
    <div class="pin">
      <div class="box">
        <img src="images/15.jpg">
      </div>
    </div>

    <div class="pin">
      <div class="box">
        <img src="images/16.jpg">
      </div>
    </div>
    <div class="pin">
      <div class="box">
        <img src="images/17.jpg">
      </div>
    </div>
    <div class="pin">
      <div class="box">
        <img src="images/18.jpg">
      </div>
    </div>
    <div class="pin">
      <div class="box">
        <img src="images/19.jpg">
      </div>
    </div>

    <div class="pin">
      <div class="box">
        <img src="images/20.jpg">
      </div>
    </div>
    <div class="pin">
      <div class="box">
        <img src="images/21.jpg">
      </div>
    </div>
  </div>
</html>

2、思路分析

首先做出静态布局来。先计算出一行放多少个元素,然后再让下一个元素放入第二行中,然后我们要计算出,放入第二行的第一个元素要放在哪个位置,故我们应该有一个数组用来存放每列的高度,当静态的这些元素都放进去之后,可以更加完善,比如当拖动滚动条的时候,页面刷新,更多元素填充,这里要用到json。

3、实现过程

1.初始的静态页面通过css来实现

2.静态的瀑布流布局,先要获取到父级对象main下面的所有类为pin的元素,然后计算一行中有几个块,此时用当前屏幕的宽度去除一个块的宽度,得到num。然后用一个数组,用来存储一行中每列的高度,通过循环,找出最小的高度,以及最小高度的下标值,然后用绝对定位设置高度。

3.当鼠标滚动的时候,通过一个函数来检查是否需要加载新的图片元素,这里用一个变量lastpinh计算出最后一个元素距离顶部的高度和自身高度的一半之和,当页面的高度与滚动出去的高度之和大于最后一个的高度时,触发事件,添加新的元素,以及调整布局。

4、需要掌握知识点:

json的数据存储

window.onscroll();
document.createElement();
obj.className;
obj.appendChild(obj1);
obj.offsetWidth/offsetHeight/offsetLeft/offsetTop;
document.documentElement.clientWidth/clientHeight;
obj.style.cssText
Math.min.apply();
Math.floor();
obj.push();
document.documentElement.scrollTop
document.body.scrollTop;

注:这些都是我所不熟练的知识点。

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

Javascript 相关文章推荐
jquery下动态显示jqGrid以及jqGrid的属性设置容易出现问题的解决方法
Oct 22 Javascript
jquery ui dialog实现弹窗特效的思路及代码
Aug 03 Javascript
jQuery实现带动画效果的二级下拉导航方法
Mar 11 Javascript
JavaScript数据类型详解
Apr 01 Javascript
AngularJS 中使用Swiper制作滚动图不能滑动的解决方法
Nov 15 Javascript
Jquery树插件zTree实现菜单树
Jan 24 Javascript
JS库之Highlight.js的用法详解
Sep 13 Javascript
webpack中如何使用雪碧图的示例代码
Nov 11 Javascript
详解VUE里子组件如何获取父组件动态变化的值
Dec 26 Javascript
详解Vue.js 作用域、slot用法(单个slot、具名slot)
Oct 15 Javascript
ElementUI 修改默认样式的几种办法(小结)
Jul 29 Javascript
小程序wx.getUserProfile接口的具体使用
Jun 02 Javascript
解决Layui 表单提交数据为空的问题
Aug 15 #Javascript
jQuery轮播图实例详解
Aug 15 #jQuery
JS实现获取毫秒值及转换成年月日时分秒的方法
Aug 15 #Javascript
对layui中表单元素的使用详解
Aug 15 #Javascript
layui中使用jquery控制radio选中事件的示例代码
Aug 15 #jQuery
vue生命周期实例小结
Aug 15 #Javascript
layui获取多选框中的值方法
Aug 15 #Javascript
You might like
PHP MYSQL乱码问题,使用SET NAMES utf8校正
2009/11/30 PHP
解析PHP生成静态html文件的三种方法
2013/06/18 PHP
PHP实现获取图片颜色值的方法
2014/07/11 PHP
php中cookie实现二级域名可访问操作的方法
2014/11/11 PHP
Yii框架表单模型和验证用法
2016/05/20 PHP
PHP面向对象程序设计之构造方法和析构方法详解
2019/06/13 PHP
IE与FireFox中的childNodes区别
2011/10/20 Javascript
javascript不可用的问题探究
2013/10/01 Javascript
jQuery实现类似标签风格的导航菜单效果代码
2015/08/25 Javascript
Javascript简单实现面向对象编程继承实例代码
2015/11/27 Javascript
js实现正则匹配中文标点符号的方法
2015/12/23 Javascript
jQuery动态改变多行文本框高度的方法
2016/09/07 Javascript
详解Nodejs的timers模块
2016/12/22 NodeJs
jQuery实现大图轮播
2017/02/13 Javascript
webpack独立打包和缓存处理详解
2017/04/03 Javascript
兼容浏览器的js事件绑定函数(详解)
2017/05/09 Javascript
js中如何完美的解析数据
2018/03/18 Javascript
浅谈React高阶组件
2018/03/28 Javascript
详解在Vue中使用TypeScript的一些思考(实践)
2018/07/06 Javascript
详解vue-cli官方脚手架配置
2018/07/20 Javascript
node.js遍历目录的方法示例
2018/08/01 Javascript
微信小程序如何加载数据库真实数据的实现
2020/03/04 Javascript
python发送邮件示例(支持中文邮件标题)
2014/02/16 Python
Python自定义进程池实例分析【生产者、消费者模型问题】
2016/09/19 Python
浅谈python函数调用返回两个或多个变量的方法
2019/01/23 Python
Django框架首页和登录页分离操作示例
2019/05/28 Python
opencv3/C++实现视频背景去除建模(BSM)
2019/12/11 Python
python中字典增加和删除使用方法
2020/09/30 Python
用python计算文件的MD5值
2020/12/23 Python
巴西电子、家电、智能手机购物网站:Girafa
2019/06/04 全球购物
外贸采购员求职的自我评价
2013/11/26 职场文书
社会学专业学生职业规划书
2014/02/07 职场文书
幼儿园大班区域活动总结
2014/07/09 职场文书
地陪导游欢迎词
2015/01/26 职场文书
大连导游词
2015/02/12 职场文书
2019最新婚庆对联集锦!
2019/07/10 职场文书