zoukankan      html  css  js  c++  java
  • 使用原生javascript实现瀑布流

    简介

    瀑布流布局是一种很常见的布局方式,他的主要视觉体验为图片元素等宽不等高,图片元素之间的水平排序参差不齐,而且随着滚动条的滚动,数据会进行异步的加载,这样的布局有两个好处,1-有视觉的冲击力,比较好看;2-图片元素能够保持原始比例,不会被拉伸。最终浏览器中看到的效果如下图:

    HTML和CSS实现步骤

    步骤1:确定html布局,代码(部分)如下

    <div id="main">
        <div class="box">
            <div class="pic">
                <img src="img/1.jpg"/>
            </div>
        </div>
        <div class="box">
            <div class="pic">
                <img src="img/2.jpg"/>
            </div>
        </div>
    </div>

    其中class=box的div主要作用是控制定位,class=pic的div的主要作用是实现各种效果,如边框阴影

    步骤2:用css实现上图的效果

    *{margin: 0px; padding: 0px;}
    #main{
        position: relative;
    }
    
    .box{
        padding: 15px 0 0 15px;
        float: left;
    }
    
    .pic{
        border: 1px solid #ccc;
        border-radius: 5px;
        box-shadow: 5px 5px 5px #CCCCCC;
        padding: 10px;
    }
    
    .pic img{
        width: 165px;
        height: auto;
    }

    注意:这里我们为什么不直接设置class=pic的margin值作为div之间的间隔,而是在外面又套了一层div呢?因为使用javascript中outerwidth属性能直接算出元素padding+margin+boder的值,而使用margin不能做到这一点。

    javascript实现步骤

    步骤1:取出所有div[class=box],放到变量var oBoxs中

    步骤2:算出屏幕可视区域能容纳div[class=box]的个数,把个数放到var cols中

    步骤3:遍历oBoxs,把前cols个div的高度放到变量oBoxsH中

    步骤4:找出oBoxsH中的最小值及其索引,把下一个div的top值设置成为oBoxsH中的最小值,left的值设置成为oBoxsH中的最小值及的索引x当前div的宽度

    步骤5:更新oBoxsH的最小值

    步骤6:判断滚动的临界点,并加载数据

     // 瀑布流主方法
    function waterfall(parent,box){
      var oParent=document.getElementById(parent);
      var oBoxs=getByClass(oParent,box);
      var cols = Math.floor(document.documentElement.offsetWidth/oBoxs[0].offsetWidth);
      var oBoxsH = [];
        for(var i=0;i<oBoxs.length;i++){
        if(i<cols){
           // 将图片的高度值添加到数组中
           oBoxsH.push(oBoxs[i].offsetHeight);
        }else{
          // 求最小值和最小值的索引
          var minBoxH = Math.min.apply(null, oBoxsH);
          var idx = getMinhIndex(oBoxsH, minBoxH);
              //计算及定义图片出现的位置
          oBoxs[i].style.position='absolute';
          oBoxs[i].style.left = oBoxs[idx].offsetLeft + 'px';
          oBoxs[i].style.top = minBoxH + 'px';
          // 改变数组值
          oBoxsH[idx] += oBoxs[i].offsetHeight;
        }
      }
    }
    // 取出所有class为clsName的元素
    function getByClass(parent,clsName){
      var boxArr=new Array(), 
          oElements=parent.getElementsByTagName('*');
      for(var i=0;i<oElements.length;i++){
        if(oElements[i].className==clsName){
          boxArr.push(oElements[i]);
        }
      }
      return boxArr;
    }
    
    // 求值在数组中的索引,arr接收的是数组,val接收的是判断的值
    function getMinhIndex(arr,val){
        for(var i=0; i<arr.length; i++) {
            if(arr[i] == val) {
                return i;
            }
        }
    }
    
    // 获取滚动时异步取数据的边界
    function checkScrollSide () {
        var oBoxs = getByClass(document.getElementById("main"), "box");// 获取所有box
        var oEltHeight = Math.floor(oBoxs[oBoxs.length-1].offsetTop + oBoxs[oBoxs.length-1].offsetHeight/2);// 当滚动的高度大小最后一个元素一半时,加载数据
        var scrollTop = document.documentElement.scrollTop || document.body.scrollTop;// 使用兼容代码
        return (oEltHeight < scrollTop + document.documentElement.clientHeight ? true : false)
    }

    绑定事件,加载数据

    var imgData = [{"src":"30.jpg"},{"src":"31.jpg"},{"src":"32.jpg"},{"src":"33.jpg"},{"src":"34.jpg"}];
    window.onload=function(){
         if(checkScrollSide()) {
            loadData();
        }
         waterfall('main','box');
         
        window.onscroll = function() {
            if(checkScrollSide()) {
                loadData();
                waterfall('main','box');
            }
        }
    }

    源代码以及素材下载地址

    Github瀑布流工程源代码:https://github.com/sunhaikuo/waterfall.git

  • 相关阅读:
    LALR(1)语法分析生成器--xbytes
    <<摩托车修理技术与禅>>读书笔记
    xscript脚本
    CentOS安装Erlang
    TCP中close和shutdown之间的区别
    Erlang高阶函数
    深度学习小记
    mac平台打造犀利的Android Studio开发环境
    MAC中如何配置两套android-sdk环境
    Ubuntu虚拟机编译Android6.0总结
  • 原文地址:https://www.cnblogs.com/sunhk/p/4304003.html
Copyright © 2011-2022 走看看