js瀑布流

 **瀑布流概念**:
        又称瀑布流式布局,是比较流行的一种网站页面布局方式。
        视觉表现为参差不齐的多栏布局,最早采用此布局的是网站是Pinterest,后逐渐在国内流行。 

 **瀑布流原理**:
           页面容器内的多个高度不固定的div之间按照一定的间隔参差不齐的无序浮动,
        鼠标滚动时不断在容器内的尾部加载数据,且自动加载到空缺位置,不断循环。

   **  优点:**

            1.有效降低了界面复杂度,节省了空间:
     不再需要臃肿复杂的页面导航链接或者按钮了; 

            2.在触屏设备上交互方式有更好的用户体验,
          通过向上滑动进行页面滚动和数据加载,对操作的精准程度要求远远低于点击按钮或者链接;

            3.更高的参与度,使用户能更好的专注于浏览而不是操作;

    ** 缺点:**

            1.无限滚动只适用与特定类型产品中的某一类型,如某类微博信息,购物网站的某类商品,而不适用与一般的门户网站,使用需斟酌;

            2.需要打造额外的js库来保证页面数据的加载和排列,而这在一定意义上增加了在网页的性能和设备兼容等方面的问题;

   **  js核心思路:**

            1.编写方法:获取容器内所有外层元素,存入数组;

            2.编写方法:计算容器内一行可以承载多少个元素,方法:容器宽度/元素宽度,四舍五入向下取整;

            3.编写方法:把每一行中所有元素的高度值存入数组;

            4.编写方法:在高度值数组中找到最小高度值;

            5.编写方法:把第二行第一个元素定位到上一行所有元素中高度最低的元素下面,即设置该元素的top,left,position属性;

            6.编写方法:重置当前高度值数组中的最小值;

            7.编写方法:从第二行第一个元素开始,遍历每个元素,用上述方法重新定位每个元素的位置,把该事件绑定到页面;

            8.编写方法:监听鼠标事件,当前容器内最下面一个元素的offsetTop<浏览器可视高度+已滚动高度时,加载下一页数据;

            9.加载完之后,用上述方法重新定位新加载元素的位置;



代码效果:
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <style>
        *{
 margin: 0px;
 padding: 0px;
}
#container{
 position: relative;
}
.box{
 padding: 7px;
 float: left;
 margin: 0px auto;
}
.box_img{
 padding: 5px;
 border: 1px solid #DCDCDC;
 box-shadow: 0 0 5px #ccc;
 border-radius: 5px;
}
.box_img img{
 width: 230px;
}
    </style>
</head>
<body>
    <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 class="box">
         <div class="box_img">
          <img src="img/4.jpg" />
         </div>
        </div>
        <div class="box">
         <div class="box_img">
          <img src="img/5.jpg" />
         </div>
        </div>
        <div class="box">
         <div class="box_img">
          <img src="img/6.jpg" />
         </div>
        </div>
        <div class="box">
         <div class="box_img">
          <img src="img/7.jpg" />
         </div>
        </div>
        <div class="box">
         <div class="box_img">
          <img src="img/3.jpg" />
         </div>
        </div>
        <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/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 class="box">
         <div class="box_img">
          <img src="img/4.jpg" />
         </div>
        </div>
        <div class="box">
         <div class="box_img">
          <img src="img/5.jpg" />
         </div>
        </div>
        <div class="box">
         <div class="box_img">
          <img src="img/6.jpg" />
         </div>
        </div>
          
       </div>
</body>
</html>
<script>

    window.onload=function(){
   
   imgLocation("container","box");
   var imgData={"data":[{"src":"1.jpg"},{"src":"2.jpg"},{"src":"3.jpg"},{"src":"3.jpg"},{"src":"4.jpg"},{"src":"5.jpg"},{"src":"6.jpg"},{"src":"2.jpg"},{"src":"3.jpg"},{"src":"3.jpg"},{"src":"4.jpg"},{"src":"5.jpg"}]}
   window.onscroll=function(){
  //  console.log(document.documentElement.scrollTop);
    if(checkFlag()){
     var cparent=document.getElementById("container");
     for(var i=0;i<imgData.data.length;i++){
      var ccontent=document.createElement("div");
      ccontent.className="box";
      cparent.appendChild(ccontent);
      var boximg=document.createElement("div");
      boximg.className="box_img";
      ccontent.appendChild(boximg);
      var img=document.createElement("img");
      img.src="img/"+imgData.data[i].src;
      boximg.appendChild(img);
        
      //另外一种方法在div后边追加内容,不覆盖原有内容
  //    var content="<div class='box'><div class='box_img'><img src='img/"+imgData.data[i].src+"'/></div></div>";
  //    cparent.innerHTML+=content;
     }
     imgLocation("container","box");
    }
   }
  }
    
  function checkFlag(){
   var cparent=document.getElementById("container");
   var ccontent=getChildElement(cparent,"box");//图片的所有box数
   var lastContentHeight=ccontent[ccontent.length-1].offsetTop;//最后一张图片距离顶部高度
   var scrollTop=document.documentElement.scrollTop||document.body.scrollTop;//滚动条距离顶部高度
   var pageHeight=document.documentElement.clientHeight||document.body.clientHeight;//屏幕高度
  // console.log(lastContentHeight+","+scrollTop+","+pageHeight);
   if(lastContentHeight<scrollTop+pageHeight){
    return true;
   }
  }
    
  function imgLocation(parent,content){
   var cparent=document.getElementById(parent);
   var ccontent=getChildElement(cparent,content);//图片的所有box数
   var imgWidth=ccontent[0].offsetWidth;//图片宽度
   var num=Math.floor(document.documentElement.clientWidth/imgWidth);//一行放图片个数
   cparent.style.cssText="width:"+imgWidth*num+"px;margin:0px auto";//container的宽度
   var boxHeightArr=[];//每一列box高度
   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);//得到最小高度下标
  //   console.log(minHeight+","+minIndex);
     ccontent[i].style.position="absolute";
     ccontent[i].style.top=minHeight+"px";//距离顶部高度
     ccontent[i].style.left=ccontent[minIndex].offsetLeft+"px";//距离左边长度
     boxHeightArr[minIndex]+=ccontent[i].offsetHeight;
  //   console.log(ccontent[i].offsetHeight+","+ccontent[i].height);//ccontent[i].height=undefined
       
    }
   }
  }
    
  function getMinheightLocation(boxHeightArr,minHeight){
   for(var i in boxHeightArr){
    if(boxHeightArr[i]==minHeight){
     return i
    }
   }
  }
    
  function getChildElement(parent,content){
   //将parent下有content的全部取出
   var contentArr=[];
   var allContent=parent.getElementsByTagName("*");
   for(i=0;i<allContent.length;i++){
    if(allContent[i].className=="box"){
     contentArr.push(allContent[i]);
    }
   }
   return contentArr;
  }
       </script>

兼容性
1 点击300ms 使用fastclick
2 移动端1px 在ios中使用0.5px
3 js中获取浏览器高度,获取scrollTOP等属性需要兼容
4 H5 的audio在ios上autoplay不会自动播放 一般使用进入页面后,使用js控制播放
5 在html上加overflow:hidden属性的时候,好多移动端浏览器都不支持
要实现超出范围隐藏,滚动条不显示,一般使用js获取高度来动态设置html高度
6 ios系统中在移动浏览器的页面中给按钮加JS事件,其按钮必须是原生HTML按钮或者由<a>标签自定义构成。
原来在IOS系统中,浏览器只支持给原生HTML按钮或<a>标签加JS事件
7 你用js 生成的一个按钮 <div class="btn">按钮</div>
在ios上直接$("#btn").click是不能加点击事件的,必须使用事件委托
8 h5页面 当输入框在最底部,点击软键盘后输入框会被遮挡。定时器或者修改为固定定位

                  setTimeout(function(){
                     document.body.scrollTop = document.body.scrollHeight;
                  },300);
               var oHeight = $(document).height(); //浏览器当前的高度
               $(window).resize(function(){ 
            if($(document).height() < oHeight){ 
            }else{ 
        $("#footer").css("position","absolute");
  } 
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,456评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,370评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,337评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,583评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,596评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,572评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,936评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,595评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,850评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,601评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,685评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,371评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,951评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,934评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,167评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,636评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,411评论 2 342