JavaScript——原生js实现瀑布流

时间:2022-11-25 10:15:25

瀑布流介绍及实现原理:

  瀑布流是一种页面布局,页面上也有多等宽的块(块就页面内容),每一块都是绝对定位(absolute),每个块排列的方式如下:寻找现在高度最小的列,把该块定位到该列下方。需要知道,浏览器的可视区域不尽相同,因此布局之前我们总要计算得到当前页面可以容下得列数,计算方法为:页面总宽度/图片宽度,将结果向下取整即可。

JavaScript——原生js实现瀑布流

 

  经过以上处理,我们可以得到每列高度都差不多得页面,也不至于每一列高度差距太大。另外,当我们将网页滚动到页面底部时,我们要加载出新的块放入网页,新的块布局方式仍与之前一致。

 下面附上实现效果:

JavaScript——原生js实现瀑布流

 

代码:

html:

 1 <!DOCTYPE html>
 2 <html>
 3     <head>
 4         <meta charset="utf-8" />
 5         <title></title>
 6         <link rel="stylesheet" type="text/css" href="css/index.css"/>
 7         <script src="js/index.js" type="text/javascript" charset="utf-8"></script>
 8     </head>
 9     <body>
10         <div class="container" id="box">        
11             <div class="item"><img src="img/1.jpg"></div>
12             <div class="item"><img src="img/2.jpg"></div>
13             <div class="item"><img src="img/3.jpg"></div>
14             <div class="item"><img src="img/4.jpg"></div>
15             <div class="item"><img src="img/5.jpg"></div>
16             <div class="item"><img src="img/6.jpg"></div>
17             <div class="item"><img src="img/7.jpg"></div>
18             <div class="item"><img src="img/8.jpg"></div>
19             <div class="item"><img src="img/9.jpg"></div>
20             <div class="item"><img src="img/10.jpg"></div>
21             <div class="item"><img src="img/11.jpg"></div>
22             <div class="item"><img src="img/12.jpg"></div>
23             <div class="item"><img src="img/13.jpg"></div>
24             <div class="item"><img src="img/14.jpg"></div>
25             <div class="item"><img src="img/15.jpg"></div>
26             <div class="item"><img src="img/16.jpg"></div>
27             <div class="item"><img src="img/17.jpg"></div>
28             <div class="item"><img src="img/18.jpg"></div>
29             <div class="item"><img src="img/19.jpg"></div>
30             <div class="item"><img src="img/20.jpg"></div>
31         </div>
32     </body>
33 </html>

css:

 1     * {
 2         margin: 0;
 3         padding: 0;
 4         position: relative;
 5     }
 6     
 7     img {
 8         display: block;
 9         width: 250px;
10     }
11     
12     .item {
13         box-shadow: 2px 2px 2px #999;
14         position: absolute;
15     }
16     

js:

 1 var i = 0;//已显示的图片数
 2 img_width=250;//图片宽度
 3 var gap = 10;// 每张图片的间隔 为10px
 4 var datas=[
 5     "C:\\Users\\crazy\\Documents\\HBuilderProjects\\瀑布流 - 副本\\img\\1.jpg","C:\\Users\\crazy\\Documents\\HBuilderProjects\\瀑布流 - 副本\\img\\10.jpg","C:\\Users\\crazy\\Documents\\HBuilderProjects\\瀑布流 - 副本\\img\\11.jpg","C:\\Users\\crazy\\Documents\\HBuilderProjects\\瀑布流 - 副本\\img\\12.jpg","C:\\Users\\crazy\\Documents\\HBuilderProjects\\瀑布流 - 副本\\img\\13.jpg","C:\\Users\\crazy\\Documents\\HBuilderProjects\\瀑布流 - 副本\\img\\14.jpg","C:\\Users\\crazy\\Documents\\HBuilderProjects\\瀑布流 - 副本\\img\\15.jpg","C:\\Users\\crazy\\Documents\\HBuilderProjects\\瀑布流 - 副本\\img\\16.jpg","C:\\Users\\crazy\\Documents\\HBuilderProjects\\瀑布流 - 副本\\img\\17.jpg","C:\\Users\\crazy\\Documents\\HBuilderProjects\\瀑布流 - 副本\\img\\18.jpg","C:\\Users\\crazy\\Documents\\HBuilderProjects\\瀑布流 - 副本\\img\\19.jpg","C:\\Users\\crazy\\Documents\\HBuilderProjects\\瀑布流 - 副本\\img\\2.jpg","C:\\Users\\crazy\\Documents\\HBuilderProjects\\瀑布流 - 副本\\img\\20.jpg","C:\\Users\\crazy\\Documents\\HBuilderProjects\\瀑布流 - 副本\\img\\21.jpg","C:\\Users\\crazy\\Documents\\HBuilderProjects\\瀑布流 - 副本\\img\\22.jpg","C:\\Users\\crazy\\Documents\\HBuilderProjects\\瀑布流 - 副本\\img\\23.jpg","C:\\Users\\crazy\\Documents\\HBuilderProjects\\瀑布流 - 副本\\img\\24.jpg","C:\\Users\\crazy\\Documents\\HBuilderProjects\\瀑布流 - 副本\\img\\25.jpg","C:\\Users\\crazy\\Documents\\HBuilderProjects\\瀑布流 - 副本\\img\\26.jpg","C:\\Users\\crazy\\Documents\\HBuilderProjects\\瀑布流 - 副本\\img\\27.jpg","C:\\Users\\crazy\\Documents\\HBuilderProjects\\瀑布流 - 副本\\img\\28.jpg","C:\\Users\\crazy\\Documents\\HBuilderProjects\\瀑布流 - 副本\\img\\29.jpg","C:\\Users\\crazy\\Documents\\HBuilderProjects\\瀑布流 - 副本\\img\\3.jpg","C:\\Users\\crazy\\Documents\\HBuilderProjects\\瀑布流 - 副本\\img\\30.jpg","C:\\Users\\crazy\\Documents\\HBuilderProjects\\瀑布流 - 副本\\img\\31.jpg","C:\\Users\\crazy\\Documents\\HBuilderProjects\\瀑布流 - 副本\\img\\32.jpg","C:\\Users\\crazy\\Documents\\HBuilderProjects\\瀑布流 - 副本\\img\\4.jpg","C:\\Users\\crazy\\Documents\\HBuilderProjects\\瀑布流 - 副本\\img\\5.jpg","C:\\Users\\crazy\\Documents\\HBuilderProjects\\瀑布流 - 副本\\img\\6.jpg","C:\\Users\\crazy\\Documents\\HBuilderProjects\\瀑布流 - 副本\\img\\7.jpg","C:\\Users\\crazy\\Documents\\HBuilderProjects\\瀑布流 - 副本\\img\\8.jpg","C:\\Users\\crazy\\Documents\\HBuilderProjects\\瀑布流 - 副本\\img\\9.jpg","C:\\Users\\crazy\\Documents\\HBuilderProjects\\瀑布流 - 副本\\img\\1.jpg","C:\\Users\\crazy\\Documents\\HBuilderProjects\\瀑布流 - 副本\\img\\10.jpg","C:\\Users\\crazy\\Documents\\HBuilderProjects\\瀑布流 - 副本\\img\\11.jpg","C:\\Users\\crazy\\Documents\\HBuilderProjects\\瀑布流 - 副本\\img\\12.jpg","C:\\Users\\crazy\\Documents\\HBuilderProjects\\瀑布流 - 副本\\img\\13.jpg","C:\\Users\\crazy\\Documents\\HBuilderProjects\\瀑布流 - 副本\\img\\14.jpg","C:\\Users\\crazy\\Documents\\HBuilderProjects\\瀑布流 - 副本\\img\\15.jpg","C:\\Users\\crazy\\Documents\\HBuilderProjects\\瀑布流 - 副本\\img\\16.jpg","C:\\Users\\crazy\\Documents\\HBuilderProjects\\瀑布流 - 副本\\img\\17.jpg","C:\\Users\\crazy\\Documents\\HBuilderProjects\\瀑布流 - 副本\\img\\18.jpg","C:\\Users\\crazy\\Documents\\HBuilderProjects\\瀑布流 - 副本\\img\\19.jpg","C:\\Users\\crazy\\Documents\\HBuilderProjects\\瀑布流 - 副本\\img\\2.jpg","C:\\Users\\crazy\\Documents\\HBuilderProjects\\瀑布流 - 副本\\img\\20.jpg","C:\\Users\\crazy\\Documents\\HBuilderProjects\\瀑布流 - 副本\\img\\21.jpg","C:\\Users\\crazy\\Documents\\HBuilderProjects\\瀑布流 - 副本\\img\\22.jpg","C:\\Users\\crazy\\Documents\\HBuilderProjects\\瀑布流 - 副本\\img\\23.jpg","C:\\Users\\crazy\\Documents\\HBuilderProjects\\瀑布流 - 副本\\img\\24.jpg","C:\\Users\\crazy\\Documents\\HBuilderProjects\\瀑布流 - 副本\\img\\25.jpg","C:\\Users\\crazy\\Documents\\HBuilderProjects\\瀑布流 - 副本\\img\\26.jpg","C:\\Users\\crazy\\Documents\\HBuilderProjects\\瀑布流 - 副本\\img\\27.jpg","C:\\Users\\crazy\\Documents\\HBuilderProjects\\瀑布流 - 副本\\img\\28.jpg","C:\\Users\\crazy\\Documents\\HBuilderProjects\\瀑布流 - 副本\\img\\29.jpg","C:\\Users\\crazy\\Documents\\HBuilderProjects\\瀑布流 - 副本\\img\\3.jpg","C:\\Users\\crazy\\Documents\\HBuilderProjects\\瀑布流 - 副本\\img\\30.jpg","C:\\Users\\crazy\\Documents\\HBuilderProjects\\瀑布流 - 副本\\img\\31.jpg","C:\\Users\\crazy\\Documents\\HBuilderProjects\\瀑布流 - 副本\\img\\32.jpg","C:\\Users\\crazy\\Documents\\HBuilderProjects\\瀑布流 - 副本\\img\\4.jpg","C:\\Users\\crazy\\Documents\\HBuilderProjects\\瀑布流 - 副本\\img\\5.jpg","C:\\Users\\crazy\\Documents\\HBuilderProjects\\瀑布流 - 副本\\img\\6.jpg","C:\\Users\\crazy\\Documents\\HBuilderProjects\\瀑布流 - 副本\\img\\7.jpg","C:\\Users\\crazy\\Documents\\HBuilderProjects\\瀑布流 - 副本\\img\\8.jpg","C:\\Users\\crazy\\Documents\\HBuilderProjects\\瀑布流 - 副本\\img\\9.jpg","C:\\Users\\crazy\\Documents\\HBuilderProjects\\瀑布流 - 副本\\img\\1.jpg","C:\\Users\\crazy\\Documents\\HBuilderProjects\\瀑布流 - 副本\\img\\10.jpg","C:\\Users\\crazy\\Documents\\HBuilderProjects\\瀑布流 - 副本\\img\\11.jpg","C:\\Users\\crazy\\Documents\\HBuilderProjects\\瀑布流 - 副本\\img\\12.jpg","C:\\Users\\crazy\\Documents\\HBuilderProjects\\瀑布流 - 副本\\img\\13.jpg","C:\\Users\\crazy\\Documents\\HBuilderProjects\\瀑布流 - 副本\\img\\14.jpg","C:\\Users\\crazy\\Documents\\HBuilderProjects\\瀑布流 - 副本\\img\\15.jpg","C:\\Users\\crazy\\Documents\\HBuilderProjects\\瀑布流 - 副本\\img\\16.jpg","C:\\Users\\crazy\\Documents\\HBuilderProjects\\瀑布流 - 副本\\img\\17.jpg","C:\\Users\\crazy\\Documents\\HBuilderProjects\\瀑布流 - 副本\\img\\18.jpg","C:\\Users\\crazy\\Documents\\HBuilderProjects\\瀑布流 - 副本\\img\\19.jpg","C:\\Users\\crazy\\Documents\\HBuilderProjects\\瀑布流 - 副本\\img\\2.jpg","C:\\Users\\crazy\\Documents\\HBuilderProjects\\瀑布流 - 副本\\img\\20.jpg","C:\\Users\\crazy\\Documents\\HBuilderProjects\\瀑布流 - 副本\\img\\21.jpg","C:\\Users\\crazy\\Documents\\HBuilderProjects\\瀑布流 - 副本\\img\\22.jpg","C:\\Users\\crazy\\Documents\\HBuilderProjects\\瀑布流 - 副本\\img\\23.jpg","C:\\Users\\crazy\\Documents\\HBuilderProjects\\瀑布流 - 副本\\img\\24.jpg","C:\\Users\\crazy\\Documents\\HBuilderProjects\\瀑布流 - 副本\\img\\25.jpg","C:\\Users\\crazy\\Documents\\HBuilderProjects\\瀑布流 - 副本\\img\\26.jpg","C:\\Users\\crazy\\Documents\\HBuilderProjects\\瀑布流 - 副本\\img\\27.jpg","C:\\Users\\crazy\\Documents\\HBuilderProjects\\瀑布流 - 副本\\img\\28.jpg","C:\\Users\\crazy\\Documents\\HBuilderProjects\\瀑布流 - 副本\\img\\29.jpg","C:\\Users\\crazy\\Documents\\HBuilderProjects\\瀑布流 - 副本\\img\\3.jpg","C:\\Users\\crazy\\Documents\\HBuilderProjects\\瀑布流 - 副本\\img\\30.jpg","C:\\Users\\crazy\\Documents\\HBuilderProjects\\瀑布流 - 副本\\img\\31.jpg","C:\\Users\\crazy\\Documents\\HBuilderProjects\\瀑布流 - 副本\\img\\32.jpg","C:\\Users\\crazy\\Documents\\HBuilderProjects\\瀑布流 - 副本\\img\\4.jpg","C:\\Users\\crazy\\Documents\\HBuilderProjects\\瀑布流 - 副本\\img\\5.jpg","C:\\Users\\crazy\\Documents\\HBuilderProjects\\瀑布流 - 副本\\img\\6.jpg","C:\\Users\\crazy\\Documents\\HBuilderProjects\\瀑布流 - 副本\\img\\7.jpg","C:\\Users\\crazy\\Documents\\HBuilderProjects\\瀑布流 - 副本\\img\\8.jpg","C:\\Users\\crazy\\Documents\\HBuilderProjects\\瀑布流 - 副本\\img\\9.jpg","C:\\Users\\crazy\\Documents\\HBuilderProjects\\瀑布流 - 副本\\img\\1.jpg","C:\\Users\\crazy\\Documents\\HBuilderProjects\\瀑布流 - 副本\\img\\10.jpg","C:\\Users\\crazy\\Documents\\HBuilderProjects\\瀑布流 - 副本\\img\\11.jpg","C:\\Users\\crazy\\Documents\\HBuilderProjects\\瀑布流 - 副本\\img\\12.jpg","C:\\Users\\crazy\\Documents\\HBuilderProjects\\瀑布流 - 副本\\img\\13.jpg","C:\\Users\\crazy\\Documents\\HBuilderProjects\\瀑布流 - 副本\\img\\14.jpg","C:\\Users\\crazy\\Documents\\HBuilderProjects\\瀑布流 - 副本\\img\\15.jpg","C:\\Users\\crazy\\Documents\\HBuilderProjects\\瀑布流 - 副本\\img\\16.jpg","C:\\Users\\crazy\\Documents\\HBuilderProjects\\瀑布流 - 副本\\img\\17.jpg","C:\\Users\\crazy\\Documents\\HBuilderProjects\\瀑布流 - 副本\\img\\18.jpg","C:\\Users\\crazy\\Documents\\HBuilderProjects\\瀑布流 - 副本\\img\\19.jpg","C:\\Users\\crazy\\Documents\\HBuilderProjects\\瀑布流 - 副本\\img\\2.jpg","C:\\Users\\crazy\\Documents\\HBuilderProjects\\瀑布流 - 副本\\img\\20.jpg","C:\\Users\\crazy\\Documents\\HBuilderProjects\\瀑布流 - 副本\\img\\21.jpg","C:\\Users\\crazy\\Documents\\HBuilderProjects\\瀑布流 - 副本\\img\\22.jpg","C:\\Users\\crazy\\Documents\\HBuilderProjects\\瀑布流 - 副本\\img\\23.jpg","C:\\Users\\crazy\\Documents\\HBuilderProjects\\瀑布流 - 副本\\img\\24.jpg","C:\\Users\\crazy\\Documents\\HBuilderProjects\\瀑布流 - 副本\\img\\25.jpg","C:\\Users\\crazy\\Documents\\HBuilderProjects\\瀑布流 - 副本\\img\\26.jpg","C:\\Users\\crazy\\Documents\\HBuilderProjects\\瀑布流 - 副本\\img\\27.jpg","C:\\Users\\crazy\\Documents\\HBuilderProjects\\瀑布流 - 副本\\img\\28.jpg","C:\\Users\\crazy\\Documents\\HBuilderProjects\\瀑布流 - 副本\\img\\29.jpg","C:\\Users\\crazy\\Documents\\HBuilderProjects\\瀑布流 - 副本\\img\\3.jpg","C:\\Users\\crazy\\Documents\\HBuilderProjects\\瀑布流 - 副本\\img\\30.jpg","C:\\Users\\crazy\\Documents\\HBuilderProjects\\瀑布流 - 副本\\img\\31.jpg","C:\\Users\\crazy\\Documents\\HBuilderProjects\\瀑布流 - 副本\\img\\32.jpg","C:\\Users\\crazy\\Documents\\HBuilderProjects\\瀑布流 - 副本\\img\\4.jpg","C:\\Users\\crazy\\Documents\\HBuilderProjects\\瀑布流 - 副本\\img\\5.jpg","C:\\Users\\crazy\\Documents\\HBuilderProjects\\瀑布流 - 副本\\img\\6.jpg","C:\\Users\\crazy\\Documents\\HBuilderProjects\\瀑布流 - 副本\\img\\7.jpg","C:\\Users\\crazy\\Documents\\HBuilderProjects\\瀑布流 - 副本\\img\\8.jpg","C:\\Users\\crazy\\Documents\\HBuilderProjects\\瀑布流 - 副本\\img\\9.jpg"
 6 ]//图片路径数组,用于模拟ajax请求获得的图片,
 7 
 8     window.onload = function() {
 9         var box = document.getElementById('box');
10         var items = box.children;//得到子元素集合
11         
12         waterFall();
13         
14         //对num张照片进行瀑布流布局
15         function waterFall() {
16             
17             //得到列数 = 页面可视区域宽度 / 图片的宽度
18             var pageWidth = getClient().width;
19             var itemWidth = img_width;
20             var columns = parseInt(pageWidth / (itemWidth + gap));
21             
22             var arr = [];//用于判断最小高度的数组
23             for (var i = 0; i < items.length; i++) {
24                 if (i < columns) {
25                     // 对第一行图片进行布局
26                     items[i].style.top = 0;
27                     items[i].style.left = (itemWidth + gap) * i + 'px';
28                     arr.push(items[i].offsetHeight);
29                 } else {
30                     // 对接下来的图片进行定位
31                     // 首先要找到数组中最小高度和它的索引
32                     var minHeight = arr[0];
33                     var index = 0;
34                     for (var j = 0; j < arr.length; j++) {
35                         if (minHeight > arr[j]) {
36                             minHeight = arr[j];
37                             index = j;
38                         }
39                     }
40                     // 设置下一行的第一个盒子位置
41                     // top值就是最小列的高度 + gap
42                     items[i].style.top = arr[index] + gap + 'px';
43                     // left值就是最小列距离左边的距离
44                     items[i].style.left = items[index].offsetLeft + 'px';
45 
46                     // 修改最小列的高度 
47                     // 最小列的高度 = 当前自己的高度 + 拼接过来的高度 + 间隙的高度
48                     arr[index] = arr[index] + items[i].offsetHeight + gap;
49                 }
50             }
51         }
52         // 页面尺寸改变时实时触发
53         window.onresize = function() {
54             waterFall();
55         };
56         
57         
58         // 当加载到底部时,从datas读取30张图片生成img并放入div,然后重新布局
59         window.onscroll = function() {
60             if (getClient().height + getScrollTop() >= items[items.length - 1].offsetTop) {          
61                 var j =0;
62                 while(j<30&&i<datas.length){
63                     var div = document.createElement("div");
64                     div.className = "item";
65                     div.innerHTML = '<img src="' + datas[i] + '" alt="">';
66                     div.firstChild.style.width=img_width;
67                     box.appendChild(div);
68                     i++;
69                     j++;
70                 }
71                 waterFall();
72             }
73 
74         };
75         
76     };
77 
78     // clientWidth 处理兼容性:获得浏览器可视区域的宽和高
79     function getClient() {
80         return {
81             width: window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth,
82             height: window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight
83         }
84     }
85     // scrollTop兼容性处理 :获得浏览器可视区域 距 整个html文档顶部的距离
86     function getScrollTop() {
87         return window.pageYOffset || document.documentElement.scrollTop;
88     }