在开发中,会遇到图片瀑布流的布局,下面,使用Jquery实现一个图片的瀑布流效果。
-
首先,要先明白瀑布流的使用情况。对于瀑布流的图片要求应当是等宽的,其大体布局如图所示:
从图中可以看到,瀑布流布局只有规律的 :
-
除第一排图片之后图片的top总是往上次top最低的图片位置上靠;
-
除第一排图片之后图片的left总是由其上面那张图片的left决定
-
有了以上 规律,便可进行代码实现,解决思路已经在代码中进行注释:
<!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>瀑布流</title> <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.5.1/jquery.min.js"></script> <style> .container { display: flex; flex-wrap: wrap; position: relative; /* justify-content: center; */ margin: 0 auto; } .box { /* 使图片的高度就是外层div的高度布局 */ display:table; } img { width: 300px; margin:10px; } </style> </head> <body> <div class="container"> <div class="box"> <img src="https://ss1.bdstatic.com/70cFuXSh_Q1YnxGkpoWK1HF6hhy/it/u=1603365312,3218205429&fm=26&gp=0.jpg" alt="" srcset=""> </div> <div class="box"> <img src="https://ss3.bdstatic.com/70cFv8Sh_Q1YnxGkpoWK1HF6hhy/it/u=3791918726,2864900975&fm=26&gp=0.jpg" alt="" srcset=""> </div> <div class="box"> <img src="https://ss1.bdstatic.com/70cFuXSh_Q1YnxGkpoWK1HF6hhy/it/u=386260428,3343317581&fm=26&gp=0.jpg" alt="" srcset=""> </div> <div class="box"> <img src="https://ss2.bdstatic.com/70cFvnSh_Q1YnxGkpoWK1HF6hhy/it/u=1822458797,1995212865&fm=26&gp=0.jpg" alt="" srcset=""> </div> <div class="box"> <img src="https://ss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=2726159083,3055171894&fm=26&gp=0.jpg" alt="" srcset=""> </div> <div class="box"> <img src="https://ss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=2033921778,648007645&fm=26&gp=0.jpg" alt="" srcset=""> </div> <div class="box"> <img src="https://ss3.bdstatic.com/70cFv8Sh_Q1YnxGkpoWK1HF6hhy/it/u=1428040234,1545850769&fm=26&gp=0.jpg" alt="" srcset=""> </div> <div class="box"> <img src="https://ss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=2728981340,289447121&fm=26&gp=0.jpg" alt="" srcset=""> </div> <div class="box"> <img src="https://ss1.bdstatic.com/70cFuXSh_Q1YnxGkpoWK1HF6hhy/it/u=2578095355,3996748034&fm=26&gp=0.jpg" alt="" srcset=""> </div> <div class="box"> <img src="https://ss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=3063337889,910174232&fm=26&gp=0.jpg" alt="" srcset=""> </div> <div class="box"> <img src="https://ss1.bdstatic.com/70cFuXSh_Q1YnxGkpoWK1HF6hhy/it/u=3828070422,3546329115&fm=26&gp=0.jpg" alt="" srcset=""> </div> <div class="box"> <img src="https://ss3.bdstatic.com/70cFv8Sh_Q1YnxGkpoWK1HF6hhy/it/u=2683323894,4026268117&fm=26&gp=0.jpg" alt="" srcset=""> </div> <div class="box"> <img src="https://ss0.bdstatic.com/70cFuHSh_Q1YnxGkpoWK1HF6hhy/it/u=1885709792,3583412796&fm=26&gp=0.jpg" alt="" srcset=""> </div> <div class="box"> <img src="https://ss0.bdstatic.com/70cFuHSh_Q1YnxGkpoWK1HF6hhy/it/u=243445625,3448531163&fm=26&gp=0.jpg" alt="" srcset=""> </div> <div class="box"> <img src="https://ss3.bdstatic.com/70cFv8Sh_Q1YnxGkpoWK1HF6hhy/it/u=2905596528,1339692195&fm=26&gp=0.jpg" alt="" srcset=""> </div> <div class="box"> <img src="https://ss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=164386111,1593788862&fm=26&gp=0.jpg" alt="" srcset=""> </div> </div> <script> // 需要图片完全加载以后,再去执行瀑布流函数【所以要使用window.onload事件】 $(window).on('load', function(){ waterFall(); $(".container").height(Math.max(document.body.scrollHeight,document.documentElement.scrollHeight)) }) function waterFall(){ // 1.获取所有的盒子 let boxs =$(".box"); // 2.获取屏幕的宽度 let winW = $(window).width(); // 3.获取每一个图片宽度 let boxW = boxs.width(); // 4.获取每一行能够摆放的图片数量并 let cols = Math.floor(winW/boxW); // 5.设置外层容器的宽度,使用整体能居中显示 $(".container").width(boxW * cols); // 4.有一个高度数组来存放每一行的高度 let heightArr = []; // 5.找到最小高度值以及对应的索引,再除第一行以外的每一张图片都应该放在对应最小高度索引值图片下方 boxs.each(function(index,item){ let boxHeight = $(item).height() if(index<cols){ // 第一排的图片的高度放入数组中 heightArr.push(boxHeight); }else{ //获取数组中的最小高度值 const minHeight = Math.min(...heightArr); // const minHeight = Math.min.apply(null, heightArr); //ES5的实现 //最小高度值对应的索引 const minIndex = heightArr.indexOf(minHeight); // 对除第一排的图片进行绝对定位 $(item).css( { position: 'absolute', left: minIndex * boxW + 'px', //最小高度值的索引*box宽度 top: minHeight + 'px', // 最小高度值 } ); heightArr[minIndex] += boxHeight; } }) } </script> </body> </html>
重要细节实现在waterFall函数那一部分,单独拆分出来(html中的图片来源于百度):
// 需要图片完全加载以后,再去执行瀑布流函数【所以要使用window.onload事件】 $(window).on('load', function(){ waterFall(); $(".container").height(Math.max(document.body.scrollHeight,document.documentElement.scrollHeight)) }) function waterFall(){ // 1.获取所有的盒子 let boxs =$(".box"); // 2.获取屏幕的宽度 let winW = $(window).width(); // 3.获取每一个图片宽度 let boxW = boxs.width(); // 4.获取每一行能够摆放的图片数量并 let cols = Math.floor(winW/boxW); // 5.设置外层容器的宽度,使用整体能居中显示 $(".container").width(boxW * cols); // 4.有一个高度数组来存放每一行的高度 let heightArr = []; // 5.找到最小高度值以及对应的索引,再除第一行以外的每一张图片都应该放在对应最小高度索引值图片下方 boxs.each(function(index,item){ let boxHeight = $(item).height() if(index<cols){ // 第一排的图片的高度放入数组中 heightArr.push(boxHeight); }else{ //获取数组中的最小高度值 const minHeight = Math.min(...heightArr); // const minHeight = Math.min.apply(null, heightArr); //ES5的实现 //最小高度值对应的索引 const minIndex = heightArr.indexOf(minHeight); // 对除第一排的图片进行绝对定位 $(item).css( { position: 'absolute', left: minIndex * boxW + 'px', //最小高度值的索引*box宽度 top: minHeight + 'px', // 最小高度值 } ); heightArr[minIndex] += boxHeight; } }) }
最终实现效果:
以上就是基于jquery的瀑布流实现,如有不正确之处,欢迎指出~