zoukankan      html  css  js  c++  java
  • 【Javascript】原生JS 实现瀑布流原理和效果, 滚动加载图片【图文解析 附源码】

    先科普下瀑布流吧

    瀑布流,又称瀑布流式布局。是当前比较流行的一种网站页面布局,视觉表现为参差不齐的多栏布局,随着页面滚动条向下滚动,这种布局还会不断加载数据块并附加至当前尾部。像瀑布一样,所以叫瀑布流,像美丽说、淘宝网都有使用过。

    这是我实现的一个效果,就是怎么滚动都加载不玩。

    这里的实现方式我们只说Js实现方法

    实现原理:

    对容器中已有数据块元素进行第一次计算

    1 容器总宽度

    2 列宽度  

    3 最小列数 ,

    得到列数后,用一个数组存放盒子所有高度,找出最小高度。之后根据序列号更新高度;看着有些拗口,实现起来就很简单了。

    对于滚动加载:即滚动到哪个高度后,需要去加载数据,其实这个就是列的最小高度值,这样当前滚动值和最小高度值比较一下即可判断出来,是否要触发加载数据;就是写一个函数,用来判断是否达到加载图片条件,如果达到,就开始加载。比如获得最后一张图片的offsetTop,可视区高度,滚动距离,也就是当图片的offsetTop小于可视区高度和滚动距离之和的情况下,此时就应该加载了,不过条件可以随便定,也可以等滚动到图片的一半时候在触发加载条件,如图所示:

    先上HTML CSS代码

      1 <!DOCTYPE html>
      2 <html lang="en">
      3 <head>
      4     <meta charset="UTF-8">
      5     <title>waterfall</title>
      6     <script src="script.js"></script>
      7     <style>
      8         * {
      9             margin: 0;
     10             padding: 0;
     11         }
     12         body {
     13             background: yellow;
     14         }
     15         #container {
     16 
     17         }
     18         #container .pin {
     19             padding-left: 15px;
     20             padding-top: 15px;
     21             float: left;
     22         }
     23         #container .div-box {
     24             float: left;
     25             border: 1px solid #ccc;
     26             box-shadow: 0 0 5px #bbb;
     27             background: #fff;
     28             padding: 12px;
     29             border-radius: 9px;
     30         }
     31         #container .div-box img {
     32             width: 300px;
     33         }
     34         #container .div-box p {
     35             text-align: center;
     36             font-size: 20px;
     37             font-weight: bold;
     38             color: red;
     39         }
     40     </style>
     41     <script>
     42         
     43     </script>
     44 </head>
     45 <body>
     46     <div id="container">
     47         <div class="pin">
     48             <div class="div-box">
     49                 <img src="img/1.jpg" alt="">
     50                 <p>白超华-博客园</p>
     51             </div>
     52         </div>
     53         <div class="pin">
     54             <div class="div-box">
     55                 <img src="img/2.jpg" alt="">
     56                 <p>白超华-博客园</p>
     57             </div>
     58         </div>
     59         <div class="pin">
     60             <div class="div-box">
     61                 <img src="img/3.jpg" alt="">
     62                 <p>白超华-博客园</p>
     63             </div>
     64         </div>
     65         <div class="pin">
     66             <div class="div-box">
     67                 <img src="img/4.jpg" alt="">
     68                 <p>白超华-博客园</p>
     69             </div>
     70         </div>
     71         <div class="pin">
     72             <div class="div-box">
     73                 <img src="img/5.jpg" alt="">
     74                 <p>白超华-博客园</p>
     75             </div>
     76         </div>
     77         <div class="pin">
     78             <div class="div-box">
     79                 <img src="img/6.jpg" alt="">
     80                 <p>白超华-博客园</p>
     81             </div>
     82         </div>
     83         <div class="pin">
     84             <div class="div-box">
     85                 <img src="img/7.jpg" alt="">
     86                 <p>白超华-博客园</p>
     87             </div>
     88         </div>
     89         <div class="pin">
     90             <div class="div-box">
     91                 <img src="img/8.jpg" alt="">
     92                 <p>白超华-博客园</p>
     93             </div>
     94         </div>
     95         <div class="pin">
     96             <div class="div-box">
     97                 <img src="img/9.jpg" alt="">
     98                 <p>白超华-博客园</p>
     99             </div>
    100         </div>
    101         <div class="pin">
    102             <div class="div-box">
    103                 <img src="img/10.jpg" alt="">
    104                 <p>白超华-博客园</p>
    105             </div>
    106         </div>
    107         <div class="pin">
    108             <div class="div-box">
    109                 <img src="img/1.jpg" alt="">
    110                 <p>白超华-博客园</p>
    111             </div>
    112         </div>
    113         <div class="pin">
    114             <div class="div-box">
    115                 <img src="img/2.jpg" alt="">
    116                 <p>白超华-博客园</p>
    117             </div>
    118         </div>
    119         <div class="pin">
    120             <div class="div-box">
    121                 <img src="img/3.jpg" alt="">
    122                 <p>白超华-博客园</p>
    123             </div>
    124         </div>
    125         <div class="pin">
    126             <div class="div-box">
    127                 <img src="img/4.jpg" alt="">
    128                 <p>白超华-博客园</p>
    129             </div>
    130         </div>
    131         <div class="pin">
    132             <div class="div-box">
    133                 <img src="img/5.jpg" alt="">
    134                 <p>白超华-博客园</p>
    135             </div>
    136         </div>
    137         <div class="pin">
    138             <div class="div-box">
    139                 <img src="img/6.jpg" alt="">
    140                 <p>白超华-博客园</p>
    141             </div>
    142         </div>
    143     </div>
    144 </body>
    145 </html>

    JS代码,每行都有注释

     1 window.onload = function(){
     2     var data = {                    //模拟后台数据 的一个JSON格式的文件
     3         "data":[
     4             {"src":"1.jpg"},
     5             {"src":"2.jpg"},
     6             {"src":"3.jpg"},
     7             {"src":"4.jpg"},
     8             {"src":"5.jpg"},
     9         ]
    10     };
    11     window.onscroll = function(){
    12         if(checkScroll()){          //判断是否具备滚动加载得条件
    13             var oParent = document.getElementById('container');
    14             for(var i=0; i<data.data.length; i++){
    15                 var div1 = document.createElement('div');  //创建div元素
    16                 div1.className = 'pin';                    //设置class
    17                 oParent.appendChild(div1);
    18                 var div2 = document.createElement('div');//创建div元素
    19                 div2.className = 'div-box';
    20                 div1.appendChild(div2);
    21                 var imgs = document.createElement('img');//创建img元素
    22                 imgs.style.width = '300px';
    23                 imgs.src = 'img/'+data.data[i].src;    //设置读取路径
    24                 div2.appendChild(imgs);
    25                 var p = document.createElement('p');//创建p元素
    26                 p.innerHTML = '白超华-博客园';
    27                 div2.appendChild(p);
    28             }
    29             waterfall('container','pin');     //--注意 别忘了这句,当滚动时候就执行
    30         }
    31     }
    32     waterfall('container','pin');
    33 }
    34 function waterfall(parent, box){
    35     var oParent = document.getElementById(parent);//获取父级对象
    36     var aBox = getByClass(oParent,box);//获取所有class为pin的盒子的集合
    37     var boxWidth = aBox[0].offsetWidth;//获取一个盒子的宽
    38     var pageWidth = document.body.clientWidth||document.documentElement.clientWidth;//获取可视区宽
    39     var cols = Math.floor(pageWidth/boxWidth);//获得列数
    40     var arrH = [];//用于存放盒子的高
    41 
    42     for(var i=0; i<aBox.length; i++){
    43         if(i<cols){//当小于第一列个数的时候
    44             arrH.push(aBox[i].offsetHeight);
    45         } else {
    46             var minH = Math.min.apply(null,arrH);//得到数组中盒字的最小高度minH;
    47             var index = getMinIndex(arrH,minH);
    48 
    49             aBox[i].style.position = 'absolute';//设置绝对定位
    50             aBox[i].style.top = minH+'px';//设置top,就是最小高度
    51             aBox[i].style.left = aBox[0].offsetWidth*index+'px';//设置left,就是一个盒子的宽*index索引数
    52             arrH[index]+=aBox[i].offsetHeight; //更新新添加盒字后的列高
    53         }
    54     }
    55 }
    56 //通过父级获取class
    57 function getByClass(parent, classname){
    58     var aClass = parent.getElementsByTagName('*');
    59     var arr = [];
    60 
    61     for(var i=0; i<aClass.length; i++){
    62         if(aClass[i].className == classname){
    63             arr.push(aClass[i]);
    64         }
    65     }
    66     return arr;
    67 }
    68 //最小值的索引index
    69 function getMinIndex(arr,val){
    70     for( i in arr){
    71         if(arr[i] == val){
    72             return i;
    73         }
    74     }
    75 }
    76 //
    77 function checkScroll(){
    78     var oParent = document.getElementById('container');
    79     var aBox = getByClass(oParent,'pin');
    80     var lastBoxHeight = aBox[aBox.length-1].offsetTop;// 当滚到到这个距离时候就开始加载
    81     var scrollTop=document.documentElement.scrollTop||document.body.scrollTop;//兼容的滚动距离
    82     var documentHeight = document.documentElement.clientHeight; //页面高度
    83     if(lastBoxHeight<scrollTop+documentHeight){
    84         return true;
    85     }
    86 }
  • 相关阅读:
    在WCF中使用Flag Enumerations
    WCF开发教程资源收集
    [转]WCF 4 安全性和 WIF 简介
    Asp.Net Web API 2 官网菜鸟学习系列导航[持续更新中]
    Asp.Net Web API 2第十八课——Working with Entity Relations in OData
    Asp.Net Web API 2第十七课——Creating an OData Endpoint in ASP.NET Web API 2(OData终结点)
    Asp.Net Web API 2第十六课——Parameter Binding in ASP.NET Web API(参数绑定)
    Asp.Net Web API 2第十五课——Model Validation(模型验证)
    函数 生成器 生成器表达式
    函数的进阶
  • 原文地址:https://www.cnblogs.com/bc8web/p/5247129.html
Copyright © 2011-2022 走看看