热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

web前端学习笔记-瀑布流的算法分析与代码实现

瀑布流效果目前应用很广泛,像花瓣,新浪轻博,蘑菇街,美丽说等好多网站都有.也有好多支持该效果的前段框架,今天学习了一下这种效果的实现,不依赖插件,自己动手分析实现过程,为了便于叙述清楚,分析中的一些名

瀑布流效果目前应用很广泛,像花瓣,新浪轻博,蘑菇街,美丽说等好多网站都有.也有好多支持该效果的前段框架,今天学习了一下这种效果的实现,不依赖插件,自己动手分析实现过程,为了便于叙述清楚,分析中的一些名词为自己拟定,不当之处还望见谅.

 

思路分析

步骤一:构建成行元素 + 寻找新增元素追加位置

瀑布流所有元素的宽度是固定的,我们用浏览器的宽度除以每个瀑布流块的宽度,就是每一行可容纳的瀑布流块的个数.因为,每个瀑布流块的高度不一,我们姑且把组成一行的这组元素称为成行元素,在成行元素放置完毕后,我们如果要再增加一个元素,那么它的位置应该这样找?

“获取成行元素集合中高度最低的那个元素,待放置的元素的top值应该是这个最低元素的高,left值应该是这个最低元素的left值”

这样,新增的这一个元素我们就找到了它存放的位置.这样成行元素中的最低高度值就变为了原来的高度+新增元素的高度.

 

步骤二:重复步骤一,依赖成行元素追加新元素

步骤一中我们已经实现了一次成行元素追加一个新的元素,这样新元素增加之后我们就构建了新的成行元素,之后的操作就是在新的成行元素中追加新元素,原理同步骤一.

步骤三:实现滚动位置监听,到底部时加载数据

代码实现

 

实现步骤一描述效果:



实现代码

doctype html>
<html>
<head>
<meta charset="UTF-8">
<title>瀑布流效果实现title>
<script type="text/Javascript" src="scripts/jquery-1.8.2.min.js">script>
<script type="text/Javascript" src="scripts/jquery.easydrag.handler.beta2.js">script>
<script type="text/Javascript">
window.onload
=function(){
//获取父级对象
var oParent = document.getElementById("main");
//获取父级[第一个参数]下的所有的子元素[按照第二个参数匹配]
var aPin = getClassObject(oParent,"pin");
//获取每一个块的宽度
var iPinW = aPin[0].offsetWidth;
// //计算每行放多少个pin(瀑布流块)页面的宽度/每一个瀑布流块的宽度
var num = Math.floor(document.documentElement.clientWidth/iPinW);
//重置父级的样式,这样保证图片整体居中
oParent.style.cssText="width:" + num*iPinW + "px;margin:0 auto;";

var compareArray = [];
//将一整行的瀑布流块的高度压入一个数组
for (var i = 0; i<num; i++) {
compareArray[i]
= aPin[i].offsetHeight;
}

//获取该行瀑布流高度最低的值
var minHeight = Math.min.apply('',compareArray);
//alert(compareArray + ",min=" + minHeight);
//获取改行高度值最小的瀑布流块的索引
var minHkey = getMinHeightKey(compareArray,minHeight);

//为新增的瀑布流块增加样式
aPin[num].style.position = "absolute";
aPin[num].style.top
= minHeight + "px";
//设定新增加的瀑布流块的top和left
aPin[num].style.left =aPin[minHkey].offsetLeft + "px";

//将该索引位置的高度改变为新增后的高度[原来瀑布流块的高度+新增的瀑布流块的高度]
compareArray[minHkey] += aPin[num].offsetHeight;

}
/**
* 获取parent下所有样式名为className的对象集合
*/
function getClassObject(parent,className){
var obj = parent.getElementsByTagName("*");
var result = [];
for(var i=0; i<obj.length;i++){
//变量如果匹配className,将匹配的对象放入数组
if(obj[i].className==className){
result.push(obj[i]);
}
}
return result;
}

/**
* 获取arr数组中值为minH的值在数组中的索引
*/
function getMinHeightKey(arr,minH){
for(key in arr){
if(arr[key] == minH){
return key;
}
}
}
script>
<style type="text/css">
/*设置每一个瀑布流块*/
#main .pin
{
width
:220px;
height
: auto;
padding
: 15px 0px 0px 15px; /*上 右 下 左*/
float
: left;
}
/*设置每一个瀑布流块中的图像样式*/
#main .pin .box
{
width
: 200px;
height
: auto;
padding
: 10px;
background
: #FFF;
border
: 1px solid #ccc;
box-shadow
: 0px 0px 6px #ccc; /*中间投影*/
border-radius
: 5px; /*圆角*/
}
#main .pin .box img
{
width
: 200px;

}
style>
head>
<body>
<div id="main">

<div class="pin">
<div class="box">
<img src="images/2012110120000859759.jpg">
div>
div>


<div class="pin">
<div class="box">
<img src="images/2012072300483800466.jpg">
div>
div>


<div class="pin">
<div class="box">
<img src="images/2012101912011350194.jpg">
div>
div>


<div class="pin">
<div class="box">
<img src="images/2012102421195356552.jpg">
div>
div>


<div class="pin">
<div class="box">
<img src="images/2012072312335411883.jpg">
div>
div>



<div class="pin">
<div class="box">
<img src="images/2012082910221472225.jpg">
div>
div>


div>
body>
html>

实现步骤二描述效果

实现代码

doctype html>
<html>
<head>
<meta charset="UTF-8">
<title>瀑布流效果实现title>
<script type="text/Javascript" src="scripts/jquery-1.8.2.min.js">script>
<script type="text/Javascript" src="scripts/jquery.easydrag.handler.beta2.js">script>
<script type="text/Javascript">
window.onload
=function(){
//获取父级对象
var oParent = document.getElementById("main");
//获取父级[第一个参数]下的所有的子元素[按照第二个参数匹配]
var aPin = getClassObject(oParent,"pin");
//获取每一个块的宽度
var iPinW = aPin[0].offsetWidth;
// //计算每行放多少个pin(瀑布流块)页面的宽度/每一个瀑布流块的宽度
var num = Math.floor(document.documentElement.clientWidth/iPinW);
//重置父级的样式,这样保证图片整体居中
oParent.style.cssText="width:" + num*iPinW + "px;margin:0 auto;";

var compareArray = [];
//遍历获取到的所有瀑布流块
for (var i = 0; i<aPin.length; i++) {
if(i<num){
//成行元素
compareArray[i] = aPin[i].offsetHeight;
}
else{
//获取成行元素中高度最低的值
var minHeight = Math.min.apply('',compareArray);
//alert(compareArray + ",min=" + minHeight);
//获取成行元素中高度最低元素的索引
var minHkey = getMinHeightKey(compareArray,minHeight);
//为新增的瀑布流块设置定位
aPin[i].style.position = "absolute";
aPin[i].style.top
= minHeight + "px";
//设定新增加的瀑布流块的top和left
aPin[i].style.left =aPin[minHkey].offsetLeft + "px";
//将该索引位置的高度改变为新增后的高度[原来瀑布流块的高度+新增的瀑布流块的高度]
compareArray[minHkey] += aPin[i].offsetHeight;
}

}

}
/**
* 获取parent下所有样式名为className的对象集合
*/
function getClassObject(parent,className){
var obj = parent.getElementsByTagName("*");
var result = [];
for(var i=0; i<obj.length;i++){
//变量如果匹配className,将匹配的对象放入数组
if(obj[i].className==className){
result.push(obj[i]);
}
}
return result;
}

/**
* 获取arr数组中值为minH的值在数组中的索引
*/
function getMinHeightKey(arr,minH){
for(key in arr){
if(arr[key] == minH){
return key;
}
}
}
script>
<style type="text/css">
/*设置每一个瀑布流块*/
#main .pin
{
width
:220px;
height
: auto;
padding
: 15px 0px 0px 15px; /*上 右 下 左*/
float
: left;
}
/*设置每一个瀑布流块中的图像样式*/
#main .pin .box
{
width
: 200px;
height
: auto;
padding
: 10px;
background
: #FFF;
border
: 1px solid #ccc;
box-shadow
: 0px 0px 6px #ccc; /*中间投影*/
border-radius
: 5px; /*圆角*/
}
#main .pin .box img
{
width
: 200px;

}
style>
head>
<body>
<div id="main">

<div class="pin">
<div class="box">
<img src="images/2012110120000859759.jpg">
div>
div>


<div class="pin">
<div class="box">
<img src="images/2012072300483800466.jpg">
div>
div>


<div class="pin">
<div class="box">
<img src="images/2012101912011350194.jpg">
div>
div>


<div class="pin">
<div class="box">
<img src="images/2012102421195356552.jpg">
div>
div>


<div class="pin">
<div class="box">
<img src="images/2012072312335411883.jpg">
div>
div>


<div class="pin">
<div class="box">
<img src="images/2012082910221472225.jpg">
div>
div>


<div class="pin">
<div class="box">
<img src="images/2012082910024626515.jpg">
div>
div>

div>
body>
html>

会看到新增的瀑布流块在新的成行元素中自动寻找高度最低的那个元素块的相对位置进行追加.添加更多元素查看效果

步骤三:实现滚动到底部时加载数据
该部分没有什么功能,只是检测滚动条的位置距离浏览器底部的相对距离进行数据加载,加载数据时创建对应的瀑布流块.判断相对距离的实现逻辑如下

 function checkScrollSite(){
var oParent = document.getElementById("main");

var aPin = getClassObject(oParent,"pin");
//加载数据依赖最后一个瀑布流块变化
var lastPinHeight = aPin[aPin.length-1].offsetTop + Math.floor(aPin[aPin.length-1].offsetHeight/2) ;
var scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
//浏览器高度
var documentH = document.documentElement.clientHeight;

if(lastPinHeight
<documentH + scrollTop){
//请求数据
return true;
}
return false;
}

在此感谢,郑印在学习上给予的指导.

转载请注明出处:[http://www.cnblogs.com/dennisit/p/3244987.html]

 


推荐阅读
  • 本文介绍了OC学习笔记中的@property和@synthesize,包括属性的定义和合成的使用方法。通过示例代码详细讲解了@property和@synthesize的作用和用法。 ... [详细]
  • 本文介绍了闭包的定义和运转机制,重点解释了闭包如何能够接触外部函数的作用域中的变量。通过词法作用域的查找规则,闭包可以访问外部函数的作用域。同时还提到了闭包的作用和影响。 ... [详细]
  • 本文介绍了使用Java实现大数乘法的分治算法,包括输入数据的处理、普通大数乘法的结果和Karatsuba大数乘法的结果。通过改变long类型可以适应不同范围的大数乘法计算。 ... [详细]
  • Webpack5内置处理图片资源的配置方法
    本文介绍了在Webpack5中处理图片资源的配置方法。在Webpack4中,我们需要使用file-loader和url-loader来处理图片资源,但是在Webpack5中,这两个Loader的功能已经被内置到Webpack中,我们只需要简单配置即可实现图片资源的处理。本文还介绍了一些常用的配置方法,如匹配不同类型的图片文件、设置输出路径等。通过本文的学习,读者可以快速掌握Webpack5处理图片资源的方法。 ... [详细]
  • Java容器中的compareto方法排序原理解析
    本文从源码解析Java容器中的compareto方法的排序原理,讲解了在使用数组存储数据时的限制以及存储效率的问题。同时提到了Redis的五大数据结构和list、set等知识点,回忆了作者大学时代的Java学习经历。文章以作者做的思维导图作为目录,展示了整个讲解过程。 ... [详细]
  • 本文讨论了如何优化解决hdu 1003 java题目的动态规划方法,通过分析加法规则和最大和的性质,提出了一种优化的思路。具体方法是,当从1加到n为负时,即sum(1,n)sum(n,s),可以继续加法计算。同时,还考虑了两种特殊情况:都是负数的情况和有0的情况。最后,通过使用Scanner类来获取输入数据。 ... [详细]
  • 在说Hibernate映射前,我们先来了解下对象关系映射ORM。ORM的实现思想就是将关系数据库中表的数据映射成对象,以对象的形式展现。这样开发人员就可以把对数据库的操作转化为对 ... [详细]
  • 本文讨论了一个关于cuowu类的问题,作者在使用cuowu类时遇到了错误提示和使用AdjustmentListener的问题。文章提供了16个解决方案,并给出了两个可能导致错误的原因。 ... [详细]
  • Voicewo在线语音识别转换jQuery插件的特点和示例
    本文介绍了一款名为Voicewo的在线语音识别转换jQuery插件,该插件具有快速、架构、风格、扩展和兼容等特点,适合在互联网应用中使用。同时还提供了一个快速示例供开发人员参考。 ... [详细]
  • 1,关于死锁的理解死锁,我们可以简单的理解为是两个线程同时使用同一资源,两个线程又得不到相应的资源而造成永无相互等待的情况。 2,模拟死锁背景介绍:我们创建一个朋友 ... [详细]
  • 本文介绍了Web学习历程记录中关于Tomcat的基本概念和配置。首先解释了Web静态Web资源和动态Web资源的概念,以及C/S架构和B/S架构的区别。然后介绍了常见的Web服务器,包括Weblogic、WebSphere和Tomcat。接着详细讲解了Tomcat的虚拟主机、web应用和虚拟路径映射的概念和配置过程。最后简要介绍了http协议的作用。本文内容详实,适合初学者了解Tomcat的基础知识。 ... [详细]
  • Java验证码——kaptcha的使用配置及样式
    本文介绍了如何使用kaptcha库来实现Java验证码的配置和样式设置,包括pom.xml的依赖配置和web.xml中servlet的配置。 ... [详细]
  • 猜字母游戏
    猜字母游戏猜字母游戏——设计数据结构猜字母游戏——设计程序结构猜字母游戏——实现字母生成方法猜字母游戏——实现字母检测方法猜字母游戏——实现主方法1猜字母游戏——设计数据结构1.1 ... [详细]
  • 目录实现效果:实现环境实现方法一:基本思路主要代码JavaScript代码总结方法二主要代码总结方法三基本思路主要代码JavaScriptHTML总结实 ... [详细]
  • 动态规划算法的基本步骤及最长递增子序列问题详解
    本文详细介绍了动态规划算法的基本步骤,包括划分阶段、选择状态、决策和状态转移方程,并以最长递增子序列问题为例进行了详细解析。动态规划算法的有效性依赖于问题本身所具有的最优子结构性质和子问题重叠性质。通过将子问题的解保存在一个表中,在以后尽可能多地利用这些子问题的解,从而提高算法的效率。 ... [详细]
author-avatar
超级独自旅行也快乐
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有