JS实现的瀑布流
程序员文章站
2022-06-01 23:29:46
...
1. HTML和CSS的布局
首先用HTML和CSS实现瀑布流的布局:如下图,为了让js可以获得盒子offsetleft等最好让盒子使用padding分开之间的距离,首先图片外面得有两层盒子,内层用来设置大盒子与图片之间的距离(给pic设置padding),外层用来设置每个图片大盒子之间的距离(给box设置padding-left和padding-top)。当然这两层盒子的大小是相同的,为了让盒子美观可以给pic设置一些CSS3的属性(box-shadow,border等)。 最后让所有的图片大盒子(box)都浮动起来,以保证,因为js加上的图要用到绝对定位所以还需要给容纳box的盒子main设置相对定位。
HTML
<body> <div id="main"> <div class="box"> <div class="pic"> <img src="img/0.jpg" /> </div> </div> <div class="box"> <div class="pic"> <img src="img/1.jpg" /> </div> </div> <div class="box"> <div class="pic"> <img src="img/2.jpg" /> </div> </div> <div class="box"> <div class="pic"> <img src="img/3.jpg" /> </div> </div> <div class="box"> <div class="pic"> <img src="img/4.jpg" /> </div> </div> <div class="box"> <div class="pic"> <img src="img/5.jpg" /> </div> </div> <div class="box"> <div class="pic"> <img src="img/6.jpg" /> </div> </div> <div class="box"> <div class="pic"> <img src="img/7.jpg" /> </div> </div> <div class="box"> <div class="pic"> <img src="img/8.jpg" /> </div> </div> </div> </body>
CSS
<style> *{margin: 0;padding: 0;} #main{ margin: 0 auto; position: relative; padding-right: 15px; /*使main居中*/ } .box{ padding: 15px 0 0 15px; float: left; } .pic{ padding: 10px; border: 1px solid black; box-shadow: 0 0 5px #000000; } .pic img{ width: 100px; height: auto; } </style>
2.JS设计
- 瀑布流函数
- 找到所有的box盒子(比较类名)
- 计算一行图片盒子box的数目:一行(box盒子)图片的数目=Math.floor(屏幕宽度/box图片宽度)
- 给main盒子设置宽度,设置了以后才可以使其居中:main的宽度 =box图片的数目*box图片的宽度
- 创建一个新的数组,存储第一行box的高度
- 保存最小高度(第一行图片高度最小值就是最小高度),并且找到它的索引号(用一个函数,比较第一行的高度值哪一个和最小高度值一样,一样则return索引号)
- 给接下来的图片设置绝对定位使它在第一行高度最小的下面,并且增加设置后那一行的高度。
function waterfall(main,box){
var main=document.getElementById(main);
var all=main.getElementsByTagName("*");
var boxArr=[]; //找到classname为box的盒子 存放box
var width=0;
for (var i=0;i<all.length;i++) {
if(all[i].className==box){
boxArr.push(all[i]);
}
}
getWidth();//刚进入页面时计算图片box的数目
function getWidth(){
//计算一行(box盒子)图片的数目=Math.floor(屏幕宽度/box图片宽度)
boxNum=Math.floor(client().width/boxArr[0].offsetWidth);
//设置main的宽度 =box图片的数目*box图片的宽度---->可以使main居中
main.style.width=boxNum*boxArr[0].offsetWidth+"px";
width=boxArr[0].offsetWidth;
}
//创建一个新的数组,存储第一行box的高度
var boxHeight=[];
for (var i=0;i<boxArr.length;i++) {
if(i<boxNum){//当第一行时,存储第一行的高度
boxHeight.push(boxArr[i].offsetHeight);
}
else{//apply改变函数/方法中this的指向
var minH=Math.min.apply(null,boxHeight); //保存最小高度
//图片的高度就是最小高度
var minIndex=getMinHIndex(boxHeight,minH);//找到最小高度的索引号
boxArr[i].style.position = "absolute";
boxArr[i].style.top=minH+"px";
boxArr[i].style.left=boxArr[minIndex].offsetLeft+"px";
boxHeight[minIndex]+=boxArr[i].offsetHeight;
}
}
function getMinHIndex(arrll,minH){//找到最小高度的索引号
for (var j=0;j<arrll.length;j++) {
if(boxHeight[j]==minH)
{
return j;
}
}
}
}
2. 下拉事件
用一个数组存储接下来图片的路径,在下拉事件里面首先判断图片是否需要加载(当最下面一行图的一半出来时),需要返回true,不需要返回false。当需要加载时新创建box盒子插入到main里面并且设置类名,再创建pic盒子插入新建的box盒子里面,设置类名,再创建img插入到新建的pic盒子里面,并且给img添加图片大小,和图片宽度(所有图片等宽)最后进行瀑布流函数。
window.onload=function(){
waterfall("main","box");//瀑布流函数
//下拉事件
var dataInt={"data":[{"src":'0.jpg'},{"src":'1.jpg'},{"src":'2.jpg'},{"src":'3.jpg'},{"src":'4.jpg'},{"src":'5.jpg'}]};
window.onscroll=function(){
if(check()){
var main=document.getElementById("main");
for(var i=0;i<dataInt.data.length;i++){
var newBox = document.createElement("div");
newBox.className="box";
main.appendChild(newBox);
var newPic = document.createElement("div");
newPic.className="pic";
newBox.appendChild(newPic);
var newImg=document.createElement("img");
newImg.src='img/'+dataInt.data[i].src;
newImg.style.width=100+"px";
newImg.className='Img';
newPic.appendChild(newImg);
}
waterfall("main","box");//瀑布流函数
}
}
}
3. 关于client和scroll的兼容
//检测scroll
function scroll(){
if(window.pageXOffset!=null){
return{
top: window.pageYOffset,
left: window.pageXOffset
}
}
else if(document.compatMode=="CSS1compat"){
return{
top: document.documentElement.scrollTop,
left: document.documentElement.scrollLeft
}
}
return{
top: document.body.scrollTop,
left: document.body.scrollLeft
}
}
//检测屏幕宽度的函数
function client(){
if(window.innerWidth!=null){
return{
width: window.innerWidth,
height: window.innerHeight
}
}
else if(window.compatMode=="CSS1compat"){
return{
width: window.documentElement.width,
height: window.documentElement.height
}
}
else{
return{
width: window.body.width,
height: window.body.height
}
}
}
3. 瀑布流完成:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<style>
*{margin: 0;padding: 0;}
#main{
margin: 0 auto;
position: relative;
padding-right: 15px;
/*使main居中*/
}
.box{
padding: 15px 0 0 15px;
float: left;
}
.pic{
padding: 10px;
border: 1px solid black;
box-shadow: 0 0 5px #000000;
}
.pic img{
width: 100px;
height: auto;
}
</style>
<script>
window.onload=function(){
waterfall("main","box");//瀑布流函数
//下拉事件
var dataInt={"data":[{"src":'0.jpg'},{"src":'1.jpg'},{"src":'2.jpg'},{"src":'3.jpg'},{"src":'4.jpg'},{"src":'5.jpg'}]};
window.onscroll=function(){
if(check()){
var main=document.getElementById("main");
for(var i=0;i<dataInt.data.length;i++){
var newBox = document.createElement("div");
newBox.className="box";
main.appendChild(newBox);
var newPic = document.createElement("div");
newPic.className="pic";
newBox.appendChild(newPic);
var newImg=document.createElement("img");
newImg.src='img/'+dataInt.data[i].src;
newImg.style.width=100+"px";
newImg.className='Img';
newPic.appendChild(newImg);
}
waterfall("main","box");//瀑布流函数
}
}
}
//加载函数
function check(){
var main = document.getElementById("main");
//取出所有的box
var box = document.getElementsByClassName("box");
var lastBoxH=box[box.length-1].offsetTop+Math.floor(box[box.length-1].offsetHeight/2);
var scrollTop=scroll().top;
var height=client().height;
return (lastBoxH<scrollTop+height)?true:false;
}
//瀑布流函数
function waterfall(main,box){
var main=document.getElementById(main);
var all=main.getElementsByTagName("*");
var boxArr=[]; //找到classname为box的盒子 存放box
var width=0;
for (var i=0;i<all.length;i++) {
if(all[i].className==box){
boxArr.push(all[i]);
}
}
getWidth();//刚进入页面时计算图片box的数目
function getWidth(){
//计算一行(box盒子)图片的数目=Math.floor(屏幕宽度/box图片宽度)
boxNum=Math.floor(client().width/boxArr[0].offsetWidth);
//设置main的宽度 =box图片的数目*box图片的宽度---->可以使main居中
main.style.width=boxNum*boxArr[0].offsetWidth+"px";
width=boxArr[0].offsetWidth;
}
//创建一个新的数组,存储第一行box的高度
var boxHeight=[];
for (var i=0;i<boxArr.length;i++) {
if(i<boxNum){//当第一行时,存储第一行的高度
boxHeight.push(boxArr[i].offsetHeight);
}
else{//apply改变函数/方法中this的指向
var minH=Math.min.apply(null,boxHeight); //保存最小高度
//图片的高度就是最小高度
var minIndex=getMinHIndex(boxHeight,minH);//找到最小高度的索引号
boxArr[i].style.position = "absolute";
boxArr[i].style.top=minH+"px";
boxArr[i].style.left=boxArr[minIndex].offsetLeft+"px";
boxHeight[minIndex]+=boxArr[i].offsetHeight;
}
}
function getMinHIndex(arrll,minH){//找到最小高度的索引号
for (var j=0;j<arrll.length;j++) {
if(boxHeight[j]==minH)
{
return j;
}
}
}
}
//公用函数
//检测scroll
function scroll(){
if(window.pageXOffset!=null){
return{
top: window.pageYOffset,
left: window.pageXOffset
}
}
else if(document.compatMode=="CSS1compat"){
return{
top: document.documentElement.scrollTop,
left: document.documentElement.scrollLeft
}
}
return{
top: document.body.scrollTop,
left: document.body.scrollLeft
}
}
//检测屏幕宽度的函数
function client(){
if(window.innerWidth!=null){
return{
width: window.innerWidth,
height: window.innerHeight
}
}
else if(window.compatMode=="CSS1compat"){
return{
width: window.documentElement.width,
height: window.documentElement.height
}
}
else{
return{
width: window.body.width,
height: window.body.height
}
}
}
</script>
</head>
<body>
<div id="main">
<div class="box">
<div class="pic">
<img src="img/0.jpg" />
</div>
</div>
<div class="box">
<div class="pic">
<img src="img/1.jpg" />
</div>
</div>
<div class="box">
<div class="pic">
<img src="img/2.jpg" />
</div>
</div>
<div class="box">
<div class="pic">
<img src="img/3.jpg" />
</div>
</div>
<div class="box">
<div class="pic">
<img src="img/4.jpg" />
</div>
</div>
<div class="box">
<div class="pic">
<img src="img/5.jpg" />
</div>
</div>
<div class="box">
<div class="pic">
<img src="img/6.jpg" />
</div>
</div>
<div class="box">
<div class="pic">
<img src="img/7.jpg" />
</div>
</div>
<div class="box">
<div class="pic">
<img src="img/8.jpg" />
</div>
</div>
<div class="box">
<div class="pic">
<img src="img/9.jpg" />
</div>
</div>
<div class="box">
<div class="pic">
<img src="img/10.jpg" />
</div>
</div>
<div class="box">
<div class="pic">
<img src="img/11.jpg" />
</div>
</div>
<div class="box">
<div class="pic">
<img src="img/12.jpg" />
</div>
</div>
<div class="box">
<div class="pic">
<img src="img/13.jpg" />
</div>
</div>
<div class="box">
<div class="pic">
<img src="img/14.jpg" />
</div>
</div>
<div class="box">
<div class="pic">
<img src="img/15.jpg" />
</div>
</div>
<div class="box">
<div class="pic">
<img src="img/16.jpg" />
</div>
</div>
<div class="box">
<div class="pic">
<img src="img/17.jpg" />
</div>
</div>
</div>
</body>
</html>