JAVASCRIPT知识点饥人谷技术博客

瀑布流,木桶,等高,圣杯,双飞翼布局

2017-04-06  本文已影响477人  饥人谷_楠柒

1.瀑布流布局

 .content{
            position:relative;
        }
 .item{
            position: absolute;
           transition:all 1s; /*渐变效果*/
         }
 function waterFull(){
                var nodeWidth =$('.item').width();//元素宽度
                var num  =parseInt($('.content').width()/nodeWidth)//一排放多少个(取整)
                var itemArr = [];//存放每列的高度;
                for(var i=0; i<num;i++){//初始化
                itemArr[i]=0;//目前每列高度为0;
            }
            
            $('.item').each(function(){//循环所有图片
                var minValue = Math.min.apply(null,itemArr) //获取数组最小值(第一次就是数组的第一项0;)
                var minIndex = itemArr.indexOf(minValue)//获取最小值的下标;

                $(this).css({//通过改变top left ;放入图片的位置;
                    top:itemArr[minIndex],
                    left:$(this).outerWidth(true)*minIndex

                })
                itemArr[minIndex] += $(this).outerHeight(true);//更改添加后列的高度
            })

     }  
20170404_183059.gif

1.在改变窗口大小时重新加载图片位置
2.当滚动时继续的加载图片;(写一个判断是否加载的函数checkScroll)
3.当滚动时发送ajax性后端要数据加载图片;(我这里是自己给的数据json模拟)
4.优化代码放入立即执行函数;

var WaterFull=(function(){
      function init(){
             waterFull()
            $(window).resize(function(){//改变窗口大小
              waterFull()
           })
            $(window).on('scroll',Scroll)//当窗口滚动时Mocks数据;
           

         }
    function waterFull(){
                var nodeWidth =$('.item').width();//元素宽度
                var num  =parseInt($('.content').width()/nodeWidth)//一排放多少个(取整)
                var itemArr = [];//存放每列的高度;
                for(var i=0; i<num;i++){//初始化
                itemArr[i]=0;//目前每列高度为0;
            }
            
            $('.item').each(function(){//循环所有图片
                var minValue = Math.min.apply(null,itemArr) //获取数组最小值(第一次就是数组的第一项0;)
                var minIndex = itemArr.indexOf(minValue)//获取最小值的下标;

                $(this).css({//通过改变top left ;放入图片的位置;
                    top:itemArr[minIndex],
                    left:$(this).outerWidth(true)*minIndex

                })
                itemArr[minIndex] += $(this).outerHeight(true);//更改添加后列的高度
            })

     }  
     function Scroll(){
          var dataInt = {
            'data':[{'src':'1.png'},{'src':'2.png'},{'src':'3.png'},{'src':'4.png'},{'src':'5.png'},{'src':'6.png'},{'src':'7.png'},
            {'src':'8.png'},{'src':'9.png'},{'src':'10.png'},{'src':'11.png'},{'src':'12.png'},{'src':'13.png'},{'src':'14.png'}]
            }
          var isArrive= false;//防止多次滚动重复数据
              if(checkScroll() && !isArrive){
                  var oParent = document.getElementsByClassName('content')[0];
                  for(var i =0;i<dataInt.data.length;i++){
                      isArrive=true;
                      var oDiv =document.createElement('div');//添加元素节点
                      oDiv.className ='item';
                      oDiv.innerHTML ='![](./img/'+dataInt.data[i].src+')'
                      oParent.appendChild(oDiv);                    
                  }
                  isArrive = false;
                  waterFull()
              }
          } 

     function checkScroll(){
             var   oParent = document.getElementsByClassName('content')[0];
             var   aDiv =oParent.getElementsByClassName('item');
             var   lastPinH=aDiv[aDiv.length-1].offsetTop+Math.floor(aDiv[aDiv.length-1].offsetHeight/2); 
             //创建【触发添加块框函数waterfall()】的高度:最后一个块框的距离网页顶部+自身高的一半(实现未滚到底就开始加载)
             var   scrollTop=$(window).scrollTop();//滚动高度
             var   winndowHeight=$(window).height(); //页面高度
             return   (lastPinH<scrollTop+winndowHeight)? true : false ; //到达指定高度后 返回true,触发waterfall()函数
        }
     return {
              init:init
          }
     })()
     
     WaterFull.init();

  function waterFull(){
             var Oparent = document.getElementById('main');
             var aPin =Oparent.getElementsByClassName('pin')//获取存储块pin的数组;
             var num =Math.floor(document.documentElement.clientWidth/aPin[0].offsetWidth)//获取窗口每行能容纳的个数
            
             var pinHArr=[];//用于存储 每列中的所有块框相加的高度
             for(var i =0 ; i<num;i++){
                 pinHArr[i]=0;
             }
             for(var i =0 ; i<aPin.length;i++){
                
                     //获取PinHArr的最小值;
                     var minValue =Math.min.apply(null,pinHArr);
                     //获取pinHArr最小值得索引;
                     var minIndex = pinHArr.indexOf(minValue);
                       
                         aPin[i].style.top=minValue+'px';//用定位改变其top值
                         aPin[i].style.left=aPin[minIndex].offsetWidth*minIndex+'px';//用定位改变其left值
                        
                     
                     pinHArr[minIndex] += aPin[i].offsetHeight;//更改添加后列的高度
                 }
             }
20170404_221332.gif
     <style>
        *{padding:0;margin:0;}
        .clearfix:after,
        .clearfix:before {
        content: " ";
        display: table;
        }
        .clearfix:after {
        clear: both;
        }
        .main {
        position: relative;
        -webkit-column-width: 222px;
        -moz-column-width: 222px;
        /*column-width 属性规定列的宽度。*/
        -webkit-column-gap: 5px;
        /*column-gap 属性规定列之间的间隔。*/
        -moz-column-gap: 5px;
        }
        .box {
        float: left;
        padding: 15px 0 0 15px;
        transition: all 1s;
        }
        .box .pic {
            width: 200px;
            height: auto;
            padding: 10px;
            border-radius: 5px;
            box-shadow: 0 0 5px #cccccc;     
        }            
       .box .pic img {
               display: block;
               width: 100%;
        }

2.木桶布局

1.当图片加载进来时,初始化new的image对象,给图片定一个高度;获取等比例下的宽度;
2.把图片的宽高放入一个空数组,通过循环数组获取图片的总宽度;
3.拿获取的总宽度跟容器宽度相比较,如果总宽度大于容器宽度,那就拿出最后一个图片的宽度,直到总宽度小于容器的宽度。然后拉伸容器里的图片让,图片填充这个容器的宽度(获取容器里现在的最后高度)
4.再把数组清空,放入刚才被拿出的最后放不下那一项(重置数组总宽度)
5.写一个函数渲染每排图片(把新高度传入进去)。

1.当图片加载进来时,初始化new的image对象,给图片定一个高度;获取等比例下的宽度;
loadImg:function(){//构建url就是一个接口;也可以是ajax;
                  var _this = this //保存作用于的this
                  var imgUrls = this.getImgUrls(40);//如果是ajax是不可能根据图片地址获取他的宽高的

                 $.each(imgUrls,function(idx,url){//所以循环这个数组,
                      var  img = new Image();//创建一个图片对象;
                      img.src =url;
                      img.onload =function(){                  
                          var imgInfo ={
                              target:$(img),//哪一张图片
                              width:200*(img.width/img.height),//  x/200=img.width/img.height
                              height:200//高度设为200;

                          }
                          _this.render(imgInfo);
                      }
                  })

               },




2.把图片的宽高放入一个空数组,通过循环数组获取图片的总宽度;
  render: function(imgInfo){
     
     
      var clientWidth = this.$ct.width();
      var rowWidth = 0;
      var newRowHeight = 0;
      var lastImgInfo = imgInfo;

      this.rowList.push(imgInfo);
      for(var i=0; i< this.rowList.length; i++){
         rowWidth = rowWidth + this.rowList[i].width;
      }


3.那获取的总宽度跟容器宽度相比较,如果总宽度大于容器宽度,那就拿出最后一个图片的宽度,直到总宽度小于容器的宽度。然后拉伸容器里的图片让,图片填充这个容器的宽度(获取容器里现在的最后高度)

 if(rowWidth > clientWidth){
        this.rowList.pop();
        rowWidth = rowWidth-lastImgInfo.width//目前每行的宽度;
        newRowHeight = clientWidth*200/rowWidth;
        //   rowWidth/200   ==  clientWidth/ X

      
      

4.再把数组清空,放入刚才被拿出的最后放不下那一项(重置数组总宽度)
         this.rowList = [];
        this.rowList.push(imgInfo);
        this.layout(newRowHeight);

5.写一个函数渲染每排图片(把新高度传入进去)
 layout: function(newRowHeight){
      console.log('createRow');
      var $rowCt = $('<div class="img-row"></div>');
      $.each(this.rowList, function(idx, imgInfo){
        var $imgCt = $('<div class="img-box"></div>'),
            $img = $(imgInfo.target);
            $img.height(newRowHeight);
            $imgCt.append($img);
            $rowCt.append($imgCt);
      });
      this.$ct.append($rowCt);

20170404_222754.gif

3.等高布局

.wrap{         
            overflow: hidden;//父容器设置超出隐藏,这样子父容器的高度就还是它里面的列没有设定padding-bottom时的高度
        }
   .left{
            float: left;
            padding-bottom: 10000px;
            margin-bottom: -10000px;
        }
        .right{
            float: right;
            padding-bottom: 10000px;
            margin-bottom: -10000px;                          
        }
20170404_165914.gif
<style>
        .wrap{
            width:100%;
            background:#ccc;
            overflow: hidden;
            min-width: 600px;
           
        }
        .left{
            width:300px;
            float: left;
            padding-bottom: 10000px;
            margin-bottom: -10000px;
            background: red;
            text-align: center;
            border: 1px saddlebrown solid;
        }
        .right{
            width:300px;
            float: right;
            padding-bottom: 10000px;
            margin-bottom: -10000px;
            background:green;
            text-align: center;
            border: 1px saddlebrown solid;
            
            
        }
        h2{
            padding: 10px;
        }
    </style>
</head>
<body>
    <div class="wrap">
        <div class="left">
           ![](./img/1.png)
           
        </div>
        <div class="right">
           ![](./img/2.png)
        </div>
    </div>
   <button class="btn1">左侧栏增加高度</button>
   <button class="btn2">右侧栏增加高度</button>
    <script src="jquery-3.2.0.min.js"></script>
    <script>
          $('.btn1').on('click',function(){
              $('.left').append('![](./img/1.png)')
          })
          $('.btn2').on('click',function(){
              $('.right').append('![](./img/2.png)')
          })
    </script>
</body>

4. 圣杯布局

        div{
             float:left;
         }
    .wrap
    {
        padding-right: 100px;//空出左右位置给左右两栏;
        padding-left:100px
    }
    .left
    {
        margin-left: -100%;//左边栏与中间拦并排;
        position: relative;
        left: -100px;//左边的div宽度大小;
    }
    .right
    {
        margin-left: -100px;//右边栏与中间拦并排;大小为右边栏宽度;
        position: relative;
        left: 100px;//左边的div宽度大小;
    }
20170404_172951.gif
 <style>
        .wrap{
            border: 1px saddlebrown solid;
            padding-left:100px;
            padding-right: 100px;
            min-width: 600px;
        }
        .clear:after{
            content:'';
            display: block;
            clear:both;
        }
        .main{
            width:100%;
            height: 200px;
            float:left;
            background:red;
        }
        .left{
            float: left;
            width:100px;
            height: 100px;
            background:green;
            margin-left: -100%;
            position: relative;
            left: -100px;

        }
       .right
               {
        float: left;
        width: 100px;
        height: 100px;
        background: pink;
        margin-left: -100px;
        position: relative;
        left: 100px;
        

    }
    </style>
</head>
<body>
     <div class="wrap clear">
        <div class="main"></div>
        <div class="left"></div>
        <div class="right"></div>
    </div>
</body>

5.双飞翼布局:

       .main
       {
        width: 100%;
        float: left;
       }
       .main .mainer//在中间div内部创建子div用于放置内容,在该子div里用margin-left和margin-right为左右两栏div留出位置
    {
        margin-left: 120px;
        margin-right: 120px;
    }
       .left
        {
            float: left;
            margin-left: -100%; //左边栏与中间拦并排;
        }
        .right
        { 
            float: left;
            margin-left: -100px; //右边栏与中间拦并排
        }
20170404_174837.gif
 .wrap
        {
            border: 1px saddlebrown solid;
            min-width: 600px;
        }
        .clear:after
       {
        content: "";
        display: block;
        clear: both;
       }
       .main
       {
        width: 100%;
        height: 200px;      
        float: left;
     

       }
       .main .mainer
    {
        background: black;
        height: 200px;
        margin-left: 120px;
        margin-right: 120px;

    }
       .left
        {
            width:100px;
            height: 100px;
            background:green;
            float: left;
            margin-left: -100%;
            
        }
        .right
        {
            width: 100px;
            height: 100px;
            background: pink;
            float: left;
            margin-left: -100px;
            
        }

    </style>
</head>
<body>
    <div class="wrap clear">
        <div class="main">
            <div class="mainer"></div>
        </div>
        <div class="left"></div>
        <div class="right"></div>
    </div>
</body>

圣杯布局和双飞翼布局解决的问题是一样的,就是两边顶宽,中间自适应的三栏布局,中间栏要在放在文档流前面以优先渲染。圣杯布局和双飞翼布局解决问题的方案在前一半是相同的,也就是三栏全部float浮动,但左右两栏加上负margin让其跟中间栏div并排,以形成三栏布局。不同在于解决”中间栏div内容不被遮挡“问题的思路不一样:圣杯布局,为了中间div内容不被遮挡,将中间div设置了左右padding-left和padding-right后,将左右两个div用相对布局position: relative并分别配合right和left属性,以便左右两栏div移动后不遮挡中间div。双飞翼布局,为了中间div内容不被遮挡,直接在中间div内部创建子div用于放置内容,在该子div里用margin-left和margin-right为左右两栏div留出位置。

6. Flex布局:

Flex布局也是很常用的布局方法可以点击链接去了解下Flex布局方法用法.
Flex布局

7.最后看下jquery实战-无限加载-jsonp-瀑布流

20170405_222202.gif

瀑布流
木桶
等高
圣杯
双飞翼

jquery实战-无限加载-jsonp-瀑布流

希望对给位朋友有所帮助~~~
版权归饥人谷__楠柒所有,如要转载请请注明出处~

上一篇下一篇

猜你喜欢

热点阅读