深入学习js瀑布流布局

本文实例为大家分享了js瀑布流布局学习资料,供大家参考,具体内容如下

特点:等宽不等高。
实现方式:Javascript/Jquery/CSS3多栏布局。
样例网站:花瓣网-->分类

一、JS实现瀑布流

index.html:页面结构

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>瀑布流布局</title>
  <link rel="stylesheet" href="styles/layout.css">
</head>
<body>
  <div id="main">
    <div class="box"><div class="pic"><img src="../waterFall/pic/0.jpg" alt=""></div></div>
    <div class="box"><div class="pic"><img src="../waterFall/pic/1.jpg" alt=""></div></div>
    <div class="box"><div class="pic"><img src="../waterFall/pic/2.jpg" alt=""></div></div>
    <div class="box"><div class="pic"><img src="../waterFall/pic/3.jpg" alt=""></div></div>
    <div class="box"><div class="pic"><img src="../waterFall/pic/4.jpg" alt=""></div></div>
    <div class="box"><div class="pic"><img src="../waterFall/pic/5.jpg" alt=""></div></div>
    <div class="box"><div class="pic"><img src="../waterFall/pic/6.jpg" alt=""></div></div>
    <div class="box"><div class="pic"><img src="../waterFall/pic/7.jpg" alt=""></div></div>
    <div class="box"><div class="pic"><img src="../waterFall/pic/8.jpg" alt=""></div></div>
    <div class="box"><div class="pic"><img src="../waterFall/pic/9.jpg" alt=""></div></div>
    <div class="box"><div class="pic"><img src="../waterFall/pic/10.jpg" alt=""></div></div>
    <div class="box"><div class="pic"><img src="../waterFall/pic/11.jpg" alt=""></div></div>
    <div class="box"><div class="pic"><img src="../waterFall/pic/12.jpg" alt=""></div></div>
    <div class="box"><div class="pic"><img src="../waterFall/pic/13.jpg" alt=""></div></div>
    <div class="box"><div class="pic"><img src="../waterFall/pic/14.jpg" alt=""></div></div>
    <div class="box"><div class="pic"><img src="../waterFall/pic/15.jpg" alt=""></div></div>
    <div class="box"><div class="pic"><img src="../waterFall/pic/16.jpg" alt=""></div></div>
    <div class="box"><div class="pic"><img src="../waterFall/pic/17.jpg" alt=""></div></div>
    <div class="box"><div class="pic"><img src="../waterFall/pic/18.jpg" alt=""></div></div>
    <div class="box"><div class="pic"><img src="../waterFall/pic/19.jpg" alt=""></div></div>
    <div class="box"><div class="pic"><img src="../waterFall/pic/20.jpg" alt=""></div></div>
    <div class="box"><div class="pic"><img src="../waterFall/pic/21.jpg" alt=""></div></div>
    <div class="box"><div class="pic"><img src="../waterFall/pic/22.jpg" alt=""></div></div>
    <div class="box"><div class="pic"><img src="../waterFall/pic/23.jpg" alt=""></div></div>
    <div class="box"><div class="pic"><img src="../waterFall/pic/24.jpg" alt=""></div></div>
    <div class="box"><div class="pic"><img src="../waterFall/pic/25.jpg" alt=""></div></div>
    <div class="box"><div class="pic"><img src="../waterFall/pic/26.jpg" alt=""></div></div>
    <div class="box"><div class="pic"><img src="../waterFall/pic/27.jpg" alt=""></div></div>
    <div class="box"><div class="pic"><img src="../waterFall/pic/28.jpg" alt=""></div></div>
    <div class="box"><div class="pic"><img src="../waterFall/pic/29.jpg" alt=""></div></div>
    <div class="box"><div class="pic"><img src="../waterFall/pic/30.jpg" alt=""></div></div>
    <div class="box"><div class="pic"><img src="../waterFall/pic/31.jpg" alt=""></div></div>
    <div class="box"><div class="pic"><img src="../waterFall/pic/32.jpg" alt=""></div></div>
    <div class="box"><div class="pic"><img src="../waterFall/pic/33.jpg" alt=""></div></div>
    <div class="box"><div class="pic"><img src="../waterFall/pic/34.jpg" alt=""></div></div>
    <div class="box"><div class="pic"><img src="../waterFall/pic/35.jpg" alt=""></div></div>
    <div class="box"><div class="pic"><img src="../waterFall/pic/36.jpg" alt=""></div></div>
    <div class="box"><div class="pic"><img src="../waterFall/pic/37.jpg" alt=""></div></div>
    <div class="box"><div class="pic"><img src="../waterFall/pic/38.jpg" alt=""></div></div>
    <div class="box"><div class="pic"><img src="../waterFall/pic/39.jpg" alt=""></div></div>
    <div class="box"><div class="pic"><img src="../waterFall/pic/40.jpg" alt=""></div></div>
    <div class="box"><div class="pic"><img src="../waterFall/pic/41.jpg" alt=""></div></div>
    <div class="box"><div class="pic"><img src="../waterFall/pic/42.jpg" alt=""></div></div>
    <div class="box"><div class="pic"><img src="../waterFall/pic/43.jpg" alt=""></div></div>
  </div>
  <script src="scripts/waterfall.js"></script>
</body>
</html>

layout.css:页面元素样式

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

waterfall.js

window.onload=function(){
  waterFall('main','box');
  //模拟后台相应数据json
  var dataInt={
    "data":
    [
     {"src":"0.jpg"},
     {"src":"1.jpg"},
     {"src":"2.jpg"},
     {"src":"3.jpg"},
     {"src":"4.jpg"},
     {"src":"5.jpg"},
     {"src":"6.jpg"}
    ]
  }
  window.onscroll=function(){
    if(checkScrollSlide){
      //将数据块渲染到当前页面的尾部
     var oParent=document.getElementById("main");
     for(var i=0;i<dataInt.data.length;i++){
       var oBox=document.createElement("div");
       oBox.className="box";
       oParent.appendChild(oBox);
       var oPic=document.createElement("div");
       oPic.className="pic";
       oBox.appendChild(oPic);
       var img=document.createElement("img");
       img.setAttribute("src",dataInt.data[i]);
       img.src="pic/"+dataInt.data[i].src;
       oPic.appendChild(img);
     }
     dataInt=null;//清空数据块,防止无限加载
     waterFall('main','box');//对页面新元素进行布局渲染
    }
  }
}
function waterFall(parent,box){
  //将main下的class为box的所有元素取出来
  var oParent=document.getElementById(parent);
  var oBoxs=getByClass(oParent,box);
  console.log(oBoxs.length);
  //计算整个页面显示的列数(页面宽/box宽)
  var oBoxW=oBoxs[0].offsetWidth;
  // console.log(oBoxW);
  var cols=Math.floor(document.documentElement.clientWidth/oBoxW);
  // console.log(cols);
  //设置main的宽
  oParent.style.cssText="width:"+oBoxW*cols+"px;margin:0 auto;"
  var hArr=[];//存放每列高度的数组
  for(var i=0;i<oBoxs.length;i++){
    if(i<cols){
      hArr.push(oBoxs[i].offsetHeight);
    }else{
      var minH=Math.min.apply(null,hArr);//获取当前数组最小高度值
      // console.log(minH);
      var index=getMinhIndex(hArr,minH);//获取数组最小高度的索引
      //console.log(index);
      oBoxs[i].style.position="absolute";//将之后的图片依次绝对定位
      oBoxs[i].style.top=minH+"px";
      oBoxs[i].style.left=index*oBoxW+"px";//计算新图片所在的位置并赋值
      hArr[index]+=oBoxs[i].offsetHeight;//变化数组列的高度值,因为加上了一张图片
    }
    //console.log(hArr);
  }

}
//根据class获取元素
function getByClass(parent,clsName){
  var boxArr=new Array(),//用来存储获取到的所有class为box的元素
    oElements=parent.getElementsByTagName("*");
    for(var i=0;i<oElements.length;i++){
      if(oElements[i].className==clsName){
        boxArr.push(oElements[i]);
      }
    }
  return boxArr;
}
function getMinhIndex(arr,val){
  for(var i=0;i<arr.length;i++){
    if(arr[i]==val){
      return i;
    }
  }

}
//检测是否具备滚动条加载数据块条件
function checkScrollSlide(){
  var oParent=document.getElementById("main");
  var oBoxs=getByClass(oParent,"box");
  var lastBoxH=oBoxs[oBoxs.length-1].offsetTop+Math.floor(oBoxs[oBoxs.length-1].offsetHeight/2);
  var scrollTop=document.body.scrollTop||document.documentElement.scrollTop;//混杂模式和标准模式下的scrollTop获取
  //console.log(scrollTop);
  var height=document.body.clientHeight||document.documentElement.clientHeight;//混杂模式和标准模式下的浏览器窗口高度获取
  return (lastBoxH<scrollTop+height)?true:false;//检测最后一个box高度是否小于滚动高度+窗口高度,返回布尔值

}

 二、JQuery    

$( window ).on( "load", function(){
  waterfall('main','pin');
  var dataInt={'data':[{'src':'1.jpg'},{'src':'2.jpg'},{'src':'3.jpg'},{'src':'4.jpg'}]};
  window.onscroll=function(){
    if(checkscrollside()){
      $.each( dataInt.data, function( index, value ){
        var $oPin = $('<div>').addClass('pin').appendTo( $( "#main" ) );
        var $oBox = $('<div>').addClass('box').appendTo( $oPin );
        $('<img>').attr('src','./images/' + $( value).attr( 'src') ).appendTo($oBox);
      });
      waterfall();
    };
  }
});

/*
  parend 父级id
  pin 元素id
*/
function waterfall(parent,pin){
  var $aPin = $( "#main>div" );
  var iPinW = $aPin.eq( 0 ).width();// 一个块框pin的宽
  var num = Math.floor( $( window ).width() / iPinW );//每行中能容纳的pin个数【窗口宽度除以一个块框宽度】
  //oParent.style.cssText='width:'+iPinW*num+'px;ma rgin:0 auto;';//设置父级居中样式:定宽+自动水平外边距
  $( "#main" ).css({
    'width:' : iPinW * num,
    'margin': '0 auto'
  });

  var pinHArr=[];//用于存储 每列中的所有块框相加的高度。

  $aPin.each( function( index, value ){
    var pinH = $aPin.eq( index ).height();
    if( index < num ){
      pinHArr[ index ] = pinH; //第一行中的num个块框pin 先添加进数组pinHArr
    }else{
      var minH = Math.min.apply( null, pinHArr );//数组pinHArr中的最小值minH
      var minHIndex = $.inArray( minH, pinHArr );
      $( value ).css({
        'position': 'absolute',
        'top': minH + 15,
        'left': $aPin.eq( minHIndex ).position().left
      });
      //数组 最小高元素的高 + 添加上的aPin[i]块框高
      pinHArr[ minHIndex ] += $aPin.eq( index ).height() + 15;//更新添加了块框后的列高
    }
  });
}

function checkscrollside(){
  var $aPin = $( "#main>div" );
  var lastPinH = $aPin.last().get(0).offsetTop + Math.floor($aPin.last().height()/2);//创建【触发添加块框函数waterfall()】的高度:最后一个块框的距离网页顶部+自身高的一半(实现未滚到底就开始加载)
  var scrollTop = $( window ).scrollTop()//注意解决兼容性
  var documentH = $( document ).height();//页面高度
  return (lastPinH < scrollTop + documentH ) ? true : false;//到达指定高度后 返回true,触发waterfall()函数
}

三、CSS多栏布局

.container{
  -webkit-column-width:160px;
  -moz-column-width:160px;
   -webkit-column-gap:5px;
   -moz-column-gap:5px;
}

/*数据块 砖块*/

.container div{width:160px;
        margin:4px 0;}

【css3和js实现方法比较】
--css3方式--
1:不需要计算,浏览器自动计算,只需设置1列宽,性能高
2:列宽随着浏览器宽口大小进行改变,用户体验不好;
3:图片排序按照垂直顺序排列,打乱图片显示顺序
4.图片加载还是需要js
--js方式--
js实现的瀑布流不会有上面的缺点,但是性能相对要差!

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

(0)

相关推荐

  • 原生js实现瀑布流布局

    用js实现瀑布流布局以及通过模拟的数据加载图片,已标记注释 效果如图: <!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8"> <title>瀑布流布局-JS实现</title> </head> <style type="text/css"> *{ margin: 0; paddin

  • javascript瀑布流布局实现方法详解

    本文实例讲述了javascript瀑布流布局实现方法.分享给大家供大家参考,具体如下: html结构: <div id="waterfall"> <div class="mod-box"> <div class="mod-img">...</div> </div> <div class="mod-box"> <div class="mod-

  • 原生JS实现美图瀑布流布局赏析

    自pinterest网站爆红以来,国内一度掀起"仿PIN"狂潮,诸如花瓣.蘑菇街等等.正是如此,"瀑布流"式布局受到广大网民的青睐.众多知名JS库,也相继出现"瀑布流"布局插件,譬如jQuery的Masonry插件.KISSY的waterfall插件等.今天闲来无聊,我也自己动手弄了段原生JS代码,实现了简单的"瀑布流"布局效果,当然肯定不能和以上那些优秀插件相提并论,有兴趣的朋友,可以去看看,希望能带给你或多或少的收获. 1

  • 原生JavaScript实现瀑布流布局

    本文实例讲解了原生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()){

  • 原生JS实现响应式瀑布流布局

    原生JS实现的瀑布流布局,代码及demo代码地址:https://github.com/leozdgao/responsive_waterfall Demo:http://leozdgao.github.io/demo/responsive_waterfall/ 演示图: 核心代码: responsive_waterfall.js (function() { var Waterfall = function(opts) { var minBoxWidth; Object.defineProper

  • 基于JavaScript实现瀑布流布局

    本文实例讲解了原生JavaScript实现瀑布流布局详细代码,分享给大家供大家参考,具体内容如下 效果图: 具体代码: HTML <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> <link rel="stylesheet" type="

  • JavaScript瀑布流布局实现代码

    先说一下什么是瀑布流布局. 就是一堆等宽不等高的数据块组成的页面,如图: 现在好多网站都采用这种瀑布流布局,如蘑菇街.美丽说等等. 首先要实现它就要明白它是怎样排列的. 每一行的列数都是根据图片的宽度和页面的宽度算比例算下来的.. 第一行就是按顺序排列,其他的数据块都是在每一列中挑选出最低的那一列依次排进去的. 首先实现框架. <div id = "main"> <div class = "box"> <div class = &quo

  • 解析瀑布流布局:JS+绝对定位的实现

    绝对定位方式的瀑布流布局: 一.布局 1.包围块框的容器: 复制代码 代码如下: <div id="main">    ... ...<div> 2.一个块框: 复制代码 代码如下: <div class="pin">    <div class="box">        <img src="./images/g (1).jpg"/>    </div>

  • 基于JavaScript实现瀑布流布局(二)

    本文实例讲解了JavaScript实现瀑布流布局详细代码,分享给大家供大家参考,具体内容如下 1.建立Html模版 想法是先用一个div container承载所有内容,然后div box用来放置图片,最后div box_border来当图片框,代码如下 <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>瀑布流</title> </head

  • 纯js实现瀑布流布局及ajax动态新增数据

    本文用纯js代码手写一个瀑布流网页效果,初步实现一个基本的瀑布流布局,以及滚动到底部后模拟ajax数据加载新图片功能. 缺点: 1. 程序不是响应式,不能实时调整页面宽度: 2. 程序中当新增ajax模拟数据图片后,是将整个页面的所有图片都重新定位一次. 3. 程序是等所有图片加载完成后再读取图片的尺寸,实际中肯定不能这样做. 4. 实际项目中,应该由后台程序给出图片尺寸值,在js代码中直接使用图片的width属性. 本程序思路: html结构: <body> <div id="

随机推荐