详解网页中的瀑布流显示效果
来源:互联网 发布:sql server 2005 教程 编辑:程序博客网 时间:2024/06/05 04:26
网页实现瀑布流显示效果
本网页基于JQuery框架。
瀑布流是什么?
瀑布流,又称瀑布流式布局。是比较流行的一种网站页面布局,视觉表现为参差不齐的多栏布局,随着页面滚动条向下滚动,这种布局还会不断加载数据块并附加至当前尾部。——摘自百度百科“瀑布流”
瀑布流布局的几个特征:
1. 单元格宽固定,高不固定。
2. 每单元格从左到右依次排列,当第一行排满后,剩余的单元格依次排在当前最短的列后。
单元格为什么可以高低错落地显示?
主要运用了元素的绝对定位,而如何正确的将不同元素定位在各自的位置,就是实现瀑布流的关键。
如何实现?
先简单的搭建网页布局,这里只需写一个单元格的代码,后续会在js中添加剩余的单元格。
单元格的内容自定,这里作为一个简单的demo仅插入一张图片,图片路径同样后续在js中添加 。
<div id="wf"> <div class="unit"> <img /> </div></div>
设置页面的CSS样式。
*{ padding: 0; margin: 0;}#wf{ margin-top: 50px; //将外层div设为相对定位,单元格才会相对于外层进行绝对定位 position: relative; }#wf .unit{ position: absolute; border: 1px solid black;}#wf .unit img{ //因下js中单元格宽度设为250px,故此将图片设为230px width: 230px; //四周各设10px内边距 padding: 10px;}
以上完成了HTML和CSS的编写,接下来是js对于功能的实现。
- 设定几个全局变量
这些全局变量在接下来的编码过程中会用到,变量值可根据个人偏好酌情设置。
//单元格宽度var unit_wid = 250;//单元格间距var unit_edge = 30;//瀑布流整体大致占比var unit_rate = 0.8;//插入单元格个数(原HTML中已设一个,故实际个数再+1)var unit_num = 9;
- 添加其余的单元格到HTML中。
//该方法需在DOM加载完成后立即执行function set_unit(){ for (var i = 0;i < unit_num;i++){ var temp = '<div class="unit"><img /></div>'; $('#wf').append(temp); }}
- 为每个单元格设置图片路径。
//该方法需在set_unit()方法完成后执行function set_img () { var img = $('#wf .unit img'); for (var i = 0;i < img.length;i++){ img.eq(i).attr('src','images/' + (i+1) + '.jpg'); }}
- 对瀑布流整体居中布局。
1). 确定整个瀑布流的页面大致占比;
2). 根据瀑布流整体宽度计算可容纳的单元格列数;
3). 计算出瀑布流整体左右外边距,使其居中显示。
var wf_wid = $(window).width() * 0.8;var num = Math.floor(wf_wid / unit_wid);//整体宽度包含num个单元格宽及num-1个间距var wf_edge = ($(window).width() - (unit_wid * num + unit_edge * (num - 1))) / 2;
- 新建数组,存放每一列的列高度,并为其赋初值0。
var heightList = [];for (var i = 0;i< num ;i++) { heightList[i] = 0;}
- 写两个接下来会用到的两个方法,一个用来获取数组中的最大值,一个用来获取数组中的最小值及最小值下标。
function getMax (arr) { var max = arr[0]; for (var i = 1;i < arr.length;i++) { if (arr[i] > max) { max = arr[i]; } } return max;}
function getMin (arr) { var min = arr[0]; var index = 0; for(var i = 1;i < arr.length;i++){ if (arr[i] < min) { min = arr[i]; index = i; } } return {min:min,index:index};}
- 为每个单元格绝对定位。
每个单元格的定位位置是实现瀑布流的关键,即要先确定单元格定位样式的top与left值。
1)列高度数组中的最小值代表了当前瀑布流最短列的高度(含单元格间距),top值直接设为该值即可。
2)列高度数组中的最小值的下标代表了最短列是哪一列(列号=下标+1),将列号-1后再乘以每一列所占宽度(含列之间边距),再加上瀑布流整体的左边距即为left最后的值。
for (var j = 0;j < $('#wf .unit').length;j++) { var col_minHeight = getMin(heightList).min; var col_minIndex = getMin(heightList).index; var initial_top = col_minHeight; //计算left值 var initial_left = col_minIndex * (unit_wid + unit_edge) + wf_edge; var unit = $('#wf .unit'); //为单元格定位 unit.eq(j).css({'top': initial_top + 'px','left': initial_left + 'px'}); //单元格定位完成后更新数组值保证后续定位 //原列高度数组最小值加上当前单元格高度及一个间距为新最小值 heightList[col_minIndex] = col_minHeight + unit.eq(j).height() + unit_edge;}
- 所有单元格定位完成后设外层div(#wf)高度。
因所有单元格均采用绝对定位,而绝对定位后的元素会脱离文档流,外层div(#wf)高度不进行设置的话默认为0,如果后续在网页中添加其他内容,新增内容会被瀑布流单元格所遮挡。
//该方法需在所有单元格定位完成后执行,传参:列高度数组的最大值function set_wfHeight (max) { //为美观,使瀑布流最高列与底部留有50px间距 var wf_height = max + 50; $('#wf').css('height',wf_height + 'px');}
至此瀑布流的初始定位全部完成,把相应代码放入同一个方法内,如下:
//该方法需在set_img()方法完成后执行function initial_position () { var wf_wid = $(window).width() * 0.8; var num = Math.floor(wf_wid / unit_wid); var wf_edge = ($(window).width() - (unit_wid * num + unit_edge * (num - 1))) / 2; var heightList = []; for (var i = 0;i< num ;i++) { heightList[i] = 0; } for (var j = 0;j < $('#wf .unit').length;j++) { var col_minHeight = getMin(heightList).min; var col_minIndex = getMin(heightList).index; var initial_top = col_minHeight; var initial_left = col_minIndex * (unit_wid + unit_edge) + wf_edge; var unit = $('#wf .unit'); unit.eq(j).css({'top': initial_top + 'px','left': initial_left + 'px'}); heightList[col_minIndex] = col_minHeight + unit.eq(j).height() + unit_edge; } set_wfHeight(getMax(heightList));}
在浏览器DOM加载完成后按次序执行各方法,如下:
$(document).ready(function(){ set_unit(); set_img(); //设置定位方法延时加载,以确保之前方法都执行完成 setTimeout("initial_position()",500);});
定位完成后的截图
还可以改进吗?
毫无疑问,现在的瀑布流还有不足,最突出的一点就是:当浏览器可视窗口变化时,我们的瀑布流依然保持原样,要改变其布局只有刷新网页。
所以,接下来我们就使瀑布流可以随着浏览器窗口的变化而变化。
1)要使瀑布流可以变化,首先要解决的就是窗口变化后新的位置的top值与left值,用initial_position()中方法获取即可。
2)获得位置后如何使单元格移动到新位置上?直接修改CSS属性可以,但太过生硬,这里我采用JQuery提供的animate()方法为这一过程设一简单的动画。
$(window).resize(function(){ var wf_wid = $(window).width()*unit_rate; var num = Math.floor(wf_wid / unit_wid); var wf_edge = ($(window).width() - (unit_wid * num + unit_edge * (num - 1))) / 2; var heightList = []; for (var i = 0;i< num ;i++) { heightList[i] = 0; } for (var j = 0;j < $('#wf .unit').length;j++) { var col_minHeight = getMin(heightList).min; var col_minIndex = getMin(heightList).index; //-----------------------与initial_position()中不同的代码段----------------------- var new_top = col_minHeight; var new_left = col_minIndex * (unit_wid + unit_edge) + wf_edge; var unit = $('#wf .unit'); //为防止窗口变化过快导致动画冲突,在执行动画前,先用stop()方法停止未完成动画 unit.eq(j).stop().animate({'top': new_top + 'px','left': new_left + 'px'},300); //-----------------------与initial_position()中不同的代码段----------------------- heightList[col_minIndex] = col_minHeight + unit.eq(j).height() + unit_edge; } set_wfHeight(getMax(heightList));});
最后放一张可动态变化的瀑布流截图
HTML代码:
<!DOCTYPE html><html> <head> <meta charset="utf-8" /> <title></title> <style> *{ margin: 0; padding: 0; } #wf{ margin-top: 50px; position: relative; } #wf .unit{ position: absolute; border: 1px solid black; } #wf .unit img{ width: 230px; padding: 10px; } </style> </head> <body> <div id="wf"> <div class="unit"> <img /> </div> </div> <script type="text/javascript" src="js/jquery-3.2.0.min.js" ></script> <script type="text/javascript" src="js/new_file.js" ></script> </body></html>
JavaScript代码:
var unit_wid = 250;var unit_edge = 30;var unit_rate = 0.8;var unit_num = 9;$(document).ready(function(){ set_unit(); set_img(); setTimeout("initial_position()",500);});function initial_position(){ var wf_wid = $(window).width()*unit_rate; var num = Math.floor(wf_wid / unit_wid); var wf_edge = ($(window).width() - (unit_wid * num + unit_edge * (num - 1))) / 2; var heightList = []; for (var i = 0;i< num ;i++) { heightList[i] = 0; } for (var j = 0;j < $('#wf .unit').length;j++) { var col_minHeight = getMin(heightList).min; var col_minIndex = getMin(heightList).index; var initial_top = col_minHeight; var initial_left = col_minIndex * (unit_wid + unit_edge) + wf_edge; var unit = $('#wf .unit'); unit.eq(j).css({'top': initial_top + 'px','left': initial_left + 'px'}); heightList[col_minIndex] = col_minHeight + unit.eq(j).height() + unit_edge; } set_wfHeight(getMax(heightList));}$(window).resize(function(){ var wf_wid = $(window).width()*unit_rate; var num = Math.floor(wf_wid / unit_wid); var wf_edge = ($(window).width() - (unit_wid * num + unit_edge * (num - 1))) / 2; var heightList = []; for (var i = 0;i< num ;i++) { heightList[i] = 0; } for (var j = 0;j < $('#wf .unit').length;j++) { var col_minHeight = getMin(heightList).min; var col_minIndex = getMin(heightList).index; var new_top = col_minHeight; var new_left = col_minIndex * (unit_wid + unit_edge) + wf_edge; var unit = $('#wf .unit'); unit.eq(j).stop().animate({'top': new_top + 'px','left': new_left + 'px'},300); heightList[col_minIndex] = col_minHeight + unit.eq(j).height() + unit_edge; } set_wfHeight(getMax(heightList));});function set_wfHeight (max) { var wf_height = max + 50; $('#wf').css('height',wf_height + 'px');}function set_img () { var img = $('#wf .unit img'); for (var i = 0;i < img.length;i++){ img.eq(i).attr('src','images/' + (i+1) + '.jpg'); }}function set_unit(){ for (var i=0;i<unit_num;i++) { var temp = '<div class="unit"><img /></div>'; $("#wf").append(temp); }}function getMax (arr) { var max = arr[0]; for (var i=1;i<arr.length;i++) { if (arr[i] > max) { max = arr[i]; } } return max;}function getMin(arr){ var min = arr[0]; var index = 0; for(var i=1;i<arr.length;i++){ if (arr[i] < min) { min = arr[i]; index = i; } } return {min:min,index:index};}
如有不足,还请各位看官见谅~
- 详解网页中的瀑布流显示效果
- 代码最少的网页瀑布流效果
- 鼠标划过div右上角显示删除叉,瀑布流效果
- 网页瀑布流设计
- android 瀑布流效果
- jQuery瀑布流效果
- ajax-瀑布流效果
- 瀑布流效果源码
- 瀑布流效果
- 瀑布流效果
- 瀑布流效果
- CSS瀑布流效果
- js 瀑布流效果
- JS 瀑布流效果
- Css3瀑布流效果
- Recyclerview 瀑布流效果
- RecyclerView实现瀑布流效果(图文详解+源码奉送)
- JavaScript的瀑布流效果的详解及实现
- 测试到底是测试什么?
- 线程间同步机制(一)
- struts2学习总结
- 图形
- POJ 1013 Counterfeit Dollar 笔记 模拟
- 详解网页中的瀑布流显示效果
- 这是一个基于Vue2实现的网易云音乐MV的webapp。
- Django数据库操作中You are trying to add a non-nullable field 'name' to contact without a default错误处理
- LintCode 翻转二叉树
- R语言矢量数据空间分析一:入门及rgeo包简介
- 关于C++类(一)
- hive合并小文件
- 如何查看Linux下面某一个目录下所有的隐藏文件和文件夹
- 递归(recursion)