瀑布流
开发时基本都是用现成的框架和开发好的插件,很少现写现用。最近感觉手写技法生疏了,遂准备实现几个常用的前端插件。首先,瀑布流。
瀑布流:渲染若干图片, 其中图片宽度相同,高度不等。
写的时候,本想找一个例子,却没找到一个例子,淘宝、蘑菇街等渲染基本规整的方块。这里找了网上的插件效果图如下:
1 不考虑使每列均匀高度
所有图片无论多高,拿到一个就加入渲染队列,即下一个若渲染就渲染当前图片,不考虑高度对图片的影响。
缺点:会造成尾部参差不齐的问题
1.1 不考虑鼠标滑动问题,仅每次滑动时生成
- 瀑布流思路:除第一行外,其余都是找到当前每一列的最小的高度,将图片加入。
大致代码如下:
<!doctype>
<html>
<head>
<style>
.box{
margin:0 auto;
position: relative;
width: 630px;
}
.img{
position: absolute;
width:200px;
background-color: red;
margin-right:10px;
margin-bottom:10px;
}
</style>
</head>
<body>
<p class="box">
</p>
<script text="text/javascript">
var x=[0,210,420],y=[0,0,0],min=0,Minindex=0;
var box = document.getElementsByClassName('box')[0];
function getMinIndex(min){
var minIndex=0
y.foreach(function(val,index,arr){
if(val==min){
minIndex=index;
return;
}
})
return minIndex;
}
//每次需要渲染时调用
function drawDiv(){
var height = Math.ceil(Math.random()*50+150);
min=Math.min(y[0],y[1],y[2]),minIndex=getMinIndex(min);
// APPend p
var imgDiv = document.createElement('p');
imgDiv.className = 'img';
imgDiv.style.left = x[minIndex]+'px';
imgDiv.style.top = y[minIndex]+'px';
imgDiv.style.height = height+'px';
box.append(imgDiv);
//add height
y[minIndex]+=height+10;
}
document.addeventlistener('mousewheel',drawDiv,false);
</script>
</body>
</html>
效果如下:
1.2 考虑每次鼠标滑动时仅加载一部分
这里考虑使用页面的总高度(含滚动区域)document.body.clientheight+document.body.scrollTop
与当前渲染的红色矩形高度最小的值比较。若滑动后,两者差值大于某一阈值(当前设置为100px)时,加载新的红色矩形,否则不操作
代码如下:
//其他部分没有更改
//每次需要渲染时调用
function drawDiv(e){
//console.dir(e);
var deltaY=e.deltaY;
//往上滑动,不操作
if(deltaY>0){
var height = Math.ceil(Math.random()*50+150);
min=Math.min(y[0],y[1],y[2]),minIndex=getMinIndex(min);
//check if all p rendered
var top = document.body.clientHeight+document.body.scrollTop;
//当滑动后距离当前最小边界值大于100时,渲染新的img;否则不操作
if(deltaY+top-min>100){
// append p
var imgDiv = document.createElement('p');
imgDiv.className = 'img';
imgDiv.style.left = x[minIndex]+'px';
imgDiv.style.top = y[minIndex]+'px';
imgDiv.style.height = height+'px';
box.append(imgDiv);
//add height
y[minIndex]+=height+10;
}
}
}
效果如下:图中滑动卡顿是由于阈值参数设置问题,在滑动过小时无法插入新的红色矩形,可修改阈值。当阈值为0,但不可避免的多渲染了;
2 考虑均匀高度
使得图片渲染后,三列图片高度差值最小(均匀高度)。
主要思路:
首先要将所有需要渲染的图片按高度排序,然后求得平均值,然后依次加入,判断是否在三列中每一列加入时均可加入,然后加入与均值差最大的那组,若加入时均超过了均值,此时应加入当前高度最小的那组。
代码如下:
<!doctype>
<html>
<head>
<style>
.box{
margin:0 auto;
position: relative;
width: 630px;
}
.img{
position: absolute;
width:200px;
background-color: red;
margin-right:10px;
margin-bottom:10px;
}
</style>
</head>
<body>
<p class="box">
</p>
<script text="text/JavaScript">
var x=[0,210,420],y=[0,0,0],min=0,minIndex=0,sum=0,imgNum=21,imgWillRender=[0,0,0],imgRendered=[0,0,0];
var heightArr=[],deap=[[],[],[]];
for(var i=0;i<imgNum;i++){
var num = Math.ceil(Math.random()*50+150);
heightArr.push(num);
sum+=num;
}
//求平均值
var average = Math.ceil(sum/3);
//排序
heightArr.sort(function(a,b){
if(a>b) return 1;
else if(a=b) return 0;
else return -1;
});
var sumArr=[0,0,0];
//判断各图片加入第几组
for(var i=imgNum-1;i>=0;i--){
min=-1,minIndex=-1;
if(sumArr[0]+heightArr[i]<=average){
var difference1 = average-sumArr[0];
min=difference1;
minIndex = 0;
}
if(sumArr[1]+heightArr[i]<=average){
var difference2 = average-sumArr[1];
if((min!=-1&&min<difference2)||min==-1){
min = difference2;
minIndex = 1;
}
}
if(sumArr[2]+heightArr[i]<=average){
var difference3= average-sumArr[2];
if((min!=-1&&min<difference3)||(min==-1)){
min = difference3;
minIndex = 2;
}
}
//若当前图片加入任何一组都超过了平均值,则加入当前高度最低的那组
if(minIndex==-1){
min=Math.min(sumArr[0],sumArr[1],sumArr[2]);
minIndex=getMinIndex(min,sumArr[0],sumArr[1],sumArr[2]);
}
deap[minIndex].push(heightArr[i]);
sumArr[minIndex]+=heightArr[i];
imgWillRender[minIndex]++;
}
var box = document.getElementsByClassName('box')[0];
function getMinIndex(min,y1,y2,y3){
var arr = new Array(y1,y2,y3);
var minIndex=0
arr.forEach(function(val,index){
if(val==min){
minIndex=index;
return;
}
})
return minIndex;
}
function renderRow(index){
//判断是否渲染完毕
if(imgRendered[index]>imgWillRender[index]-1) return;
// append p
var imgDiv = document.createElement('p');
imgDiv.className = 'img';
imgDiv.style.left = x[index]+'px';
imgDiv.style.top = y[index]+'px';
imgDiv.style.height = deap[index][imgRendered[index]]+'px';
box.append(imgDiv);
//add height
y[index]+=deap[index][imgRendered[index]]+10;
imgRendered[index]++;
}
//每次需要渲染时调用
function drawDiv(e){
var deltaY=e.deltaY;
//往上滑动,不操作
if(deltaY>0){
var min=Math.min(y[0],y[1],y[2]),minIndex=getMinIndex(min,y[0],y[1],y[2]);
var top = document.body.clientHeight+document.body.scrollTop;
//当滑动后距离当前最小边界值大于100时,渲染新的img;否则不操作
if(deltaY+top-y[0]>0){
renderRow(0);
}
if(deltaY+top-y[1]>0){
renderRow(1);
}
if(deltaY+top-y[2]>0){
renderRow(2);
}
}
}
document.addEventListener('mousewheel',drawDiv,false);
</script>
</body>
</html>
效果如下:
相关阅读
1、登陆开发者官网: https://developer.apple.com/ 2、如果有苹果设备,可以直接使用你设备的appleID,后面的步骤一样的,这是少了这个
我们用app时,有发现有很多app会出现欢迎页面.还有就是向导页面,比如你第一次使用某个app时,会出现一系列向导页面.这些东西的实现
使用外网访问Microsoft 远程桌面(Microsoft Remote De
就在昨天博主发现有一款微软官方的APP可以实现在手机上远程操控电脑,抱着玩一玩心态下下来,使用之后发现不愧是官方应用,远程操作起
在这里我主要是解说一下Vncviewer的简单使用步骤以及使用当中要注意的事项!对着搞就行了. 一、进入后记得将服务器的ID改为你要连
此文已由作者张青授权网易云社区发布。欢迎访问网易云社区,了解更多网易技术产品运营经验。赞,它的名字叫“小海豚”(我起的小名),大名