详解网页中的瀑布流显示效果
2017-04-21 20:15
507 查看
网页实现瀑布流显示效果
本网页基于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 = [];
a164
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};
}
如有不足,还请各位看官见谅~
相关文章推荐
- wpf 客户端【JDAgent桌面助手】开发详解(三) 瀑布流效果实现与UI虚拟化优化大数据显示
- top、postop、scrolltop、scrollHeight、offsetHeight详解以及各浏览器显示效果差异
- 2016/3/26 weixin 头像 昵称 网页优化显示 缺表中数据 只有代码 无显示效果
- Android RecyclerView详解之实现 ListView GridView瀑布流效果
- 在网页上显示漂浮移动效果
- JS实现可直接显示网页代码运行效果的HTML代码预览功能实例
- 卷帘一样的文字显示效果,为你的网页增加不少生色哦!
- 让png格式图片在网页中透明显示,让IE8支持半透明效果滤镜
- 实现网页背景变暗,显示信息提示效果!
- 卷帘一样的文字显示效果,为你的网页增加不少生色哦!
- 卷帘一样的文字显示效果,为你的网页增加不少生色哦!
- 网页瀑布流效果实现的几种方式
- jQuery实现基本隐藏与显示效果的方法详解
- Ueditor编辑保存的内容网页显示时背景等信息无效果---参考UEditor官方文档之编辑内容展示
- 让png格式图片在网页中透明显示,让IE8支持半透明效果滤镜
- 网页加载过渡效果详解
- CSS,background-image网页效果不显示问题
- 【凯子哥带你做高仿】“煎蛋”Android版的高仿及优化(二)——大图显示模式、评论“盖楼”效果实现详解
- 让png格式图片在网页中透明显示,让IE8支持半透明效果滤镜
- 一个在线测试网页在不同分辨率下显示效果的网站