网络编程
位置:首页>> 网络编程>> JavaScript>> 纯js实现瀑布流布局及ajax动态新增数据

纯js实现瀑布流布局及ajax动态新增数据

作者:WoodK  发布时间:2023-08-08 07:11:23 

标签:js,瀑布流,布局

本文用纯js代码手写一个瀑布流网页效果,初步实现一个基本的瀑布流布局,以及滚动到底部后模拟ajax数据加载新图片功能。

缺点:

1. 程序不是响应式,不能实时调整页面宽度;

2. 程序中当新增ajax模拟数据图片后,是将整个页面的所有图片都重新定位一次。

3. 程序是等所有图片加载完成后再读取图片的尺寸,实际中肯定不能这样做。

4. 实际项目中,应该由后台程序给出图片尺寸值,在js代码中直接使用图片的width属性。 

本程序思路:

html结构:


<body>
<div id="container">
 <div class="box">
  <div class="box_img">
   <img src="img/1.jpg" />
  </div>
 </div>
 <div class="box">
  <div class="box_img">
   <img src="img/2.jpg" />
  </div>
 </div>
 ...
</div>
</body>

一、初始化布局

1. 设置#container为position:relative;

2. 设置.box为float:left;

3. 网页加载后对所有图片进行定位;

3.1 图片宽度是固定的,计算出当前页面每行能容纳的图片数num,并得出#container的宽度,然后设置页面居中;

3.2 循环遍历所有图片,前num个图片默认float布局作为第一行,并存入数组BoxHeightArr = [];

3.3 第一行布局完成后,排布下一个图片,并更新BoxHeightArr[]:

3.3.1 将下一个图片放到第一行最矮图片的下方(用position:absolute定位),也就是BoxHeightArr[]中高度最小的那一列,记录下列数的索引值:minIndex;

3.3.2 更新BoxHeightArr[]中最小的那个值(BoxHeightArr[minIndex]+当前图片的高度);

3.4 重复循环3.3步骤,直到所有图片都排布完成

二、实时监测滚动高度,是否要加载新数据

1.初始化完成后得到最后一个图片距离顶部的高度: lastContentHeight

2.用window.onscroll = function(){...}

实时监测当前页面的滚动高度为:scrollTop

实时监测当前页面视窗高度为:pageHeight

3. 当页面监测到:lastContentHeight < scrollTop + pageHeight 时,用ajax获取新增图片的json数据。

三、页面底部新增内容

1. 用一个循环,先创建一个新的图片容器,添加到底部,然后将json数据中相应的图片数据如路径等信息写入该容器完成添加图片。

2. 所有新增图片添加完成后,对整个页面的所有图片及布局重新执行步骤一的初始化操作。

 项目文件夹:

纯js实现瀑布流布局及ajax动态新增数据

index.html: 预先置入部分图片数据


<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<link rel="stylesheet" type="text/css" href="css/style.css"/>
<script src="js/app.js"></script>
<title>JavaScript瀑布流</title>
</head>
<body>
<div id="container">
 <div class="box">
 <div class="box_img">
  <img src="img/1.jpg"/>
 </div>
 </div>
 <div class="box">
 <div class="box_img">
  <img src="img/2.jpg"/>
 </div>
 </div>
 <div class="box">
 <div class="box_img">
  <img src="img/3.jpg"/>
 </div>
 </div>
 <div class="box">
 <div class="box_img">
  <img src="img/4.jpg"/>
 </div>
 </div>
 <div class="box">
 <div class="box_img">
  <img src="img/5.jpg"/>
 </div>
 </div>
 <div class="box">
 <div class="box_img">
  <img src="img/6.jpg"/>
 </div>
 </div>
 <div class="box">
 <div class="box_img">
  <img src="img/7.jpg"/>
 </div>
 </div>
 <div class="box">
 <div class="box_img">
  <img src="img/8.jpg"/>
 </div>
 </div>
 <div class="box">
 <div class="box_img">
  <img src="img/9.jpg"/>
 </div>
 </div>
 <div class="box">
 <div class="box_img">
  <img src="img/10.jpg"/>
 </div>
 </div>

<div class="box">
 <div class="box_img">
  <img src="img/1.jpg"/>
 </div>
 </div>
 <div class="box">
 <div class="box_img">
  <img src="img/2.jpg"/>
 </div>
 </div>
 <div class="box">
 <div class="box_img">
  <img src="img/3.jpg"/>
 </div>
 </div>
 <div class="box">
 <div class="box_img">
  <img src="img/4.jpg"/>
 </div>
 </div>
 <div class="box">
 <div class="box_img">
  <img src="img/5.jpg"/>
 </div>
 </div>
 <div class="box">
 <div class="box_img">
  <img src="img/6.jpg"/>
 </div>
 </div>
 <div class="box">
 <div class="box_img">
  <img src="img/7.jpg"/>
 </div>
 </div>
 <div class="box">
 <div class="box_img">
  <img src="img/8.jpg"/>
 </div>
 </div>
 <div class="box">
 <div class="box_img">
  <img src="img/9.jpg"/>
 </div>
 </div>

<div class="box">
 <div class="box_img">
  <img src="img/10.jpg"/>
 </div>
 </div>

<div class="box">
 <div class="box_img">
  <img src="img/1.jpg"/>
 </div>
 </div>
 <div class="box">
 <div class="box_img">
  <img src="img/2.jpg"/>
 </div>
 </div>
 <div class="box">
 <div class="box_img">
  <img src="img/3.jpg"/>
 </div>
 </div>
 <div class="box">
 <div class="box_img">
  <img src="img/4.jpg"/>
 </div>
 </div>
 <div class="box">
 <div class="box_img">
  <img src="img/5.jpg"/>
 </div>
 </div>
 <div class="box">
 <div class="box_img">
  <img src="img/6.jpg"/>
 </div>
 </div>
 <div class="box">
 <div class="box_img">
  <img src="img/7.jpg"/>
 </div>
 </div>
 <div class="box">
 <div class="box_img">
  <img src="img/8.jpg"/>
 </div>
 </div>
 <div class="box">
 <div class="box_img">
  <img src="img/9.jpg"/>
 </div>
 </div>
 <div class="box">
 <div class="box_img">
  <img src="img/9.jpg"/>
 </div>
 </div>
 <div class="box">
 <div class="box_img">
  <img src="img/10.jpg"/>
 </div>
 </div>
</div>
</body>
</html>

style.css:


*{
margin: 0;
padding: 0;
}
#container{
position: relative;
}
.box{
padding: 5px;
float: left;
}
.box_img{
padding: 5px;
border: 1px solid #ccc;
box-shadow: 0 0 5px #ccc;
border-radius: 5px;
}
.box_img img{
width: 150px;
height: auto;
}

app.js:


window.onload = function(){
imgLocation("container", "box");
//ajax模拟数据
var imgData = {"data":[{"src":"2.jpg"},{"src":"3.jpg"},{"src":"4.jpg"},{"src":"5.jpg"},{"src":"6.jpg"},{"src":"8.jpg"},{"src":"2.jpg"},{"src":"3.jpg"},{"src":"4.jpg"},{"src":"5.jpg"},{"src":"6.jpg"},{"src":"8.jpg"}]}

window.onscroll = function(){
if(checkFlag()){ //判断是否到底部要加载新的数据
 var cparent = document.getElementById("container");
 //把ajax数据加载进页面
 for(var i=0; i<imgData.data.length; i++){
 var ccontent = document.createElement("div");
 ccontent.className="box";
 cparent.appendChild(ccontent);
 var boximg = document.createElement("div");
 boximg.className = "box_img";
 ccontent.appendChild(boximg);
 var img = document.createElement("img");
 img.src = "img/"+imgData.data[i].src;
 boximg.appendChild(img);
 }
 //把所有图片数据重新定位一次
 imgLocation("container", "box");
}
}
};

function checkFlag(){
var cparent = document.getElementById("container");
var ccontent = getChildElement(cparent, "box");

//得到最后一张图距顶部的高度,滚动高度,窗口高度
var lastContentHeight = ccontent[ccontent.length-1].offsetTop;
var scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
var pageHeight = document.documentElement.clientHeight || document.body.clientHeight;
console.log(lastContentHeight+":"+scrollTop+":"+pageHeight);

if(lastContentHeight < scrollTop + pageHeight){
return true;
}
}

function imgLocation(parent, content){
//将parent下所有的content全部取出
var cparent = document.getElementById(parent);
var ccontent = getChildElement(cparent, content);
//根据当前浏览器窗口的宽度,确定每行图片数并固定,居中
var imgWidth = ccontent[0].offsetWidth; //offsetWidth = width + padding + border
var num = Math.floor(document.documentElement.clientWidth / imgWidth);
cparent.style.cssText = "width:"+imgWidth*num+"px;margin:0 auto";
//alert("pause");
//设置一个数组,用来承载第一行的图片信息
var BoxHeightArr = [];
for(var i=0; i<ccontent.length; i++){
if(i<num){
 //第一行的图片的高度记录下来
 BoxHeightArr[i] = ccontent[i].offsetHeight;
 //当ajax数据加载后,程序是将所有图片重新定位,所以第一行的图片要清除position:absolute
 ccontent[i].style.position = "static";
}else{
 var minHeight = Math.min.apply(null, BoxHeightArr);
 var minIndex = getminheightLocation(BoxHeightArr, minHeight);

//把图放在第一行图索引值最小的下面
 ccontent[i].style.position = "absolute";
 ccontent[i].style.top = minHeight+"px";
 ccontent[i].style.left = ccontent[minIndex].offsetLeft+"px";

//图片放好位置后更新“第一行图片信息的最小高度”,
 //然后利用for循环重复这个动作到结束
 BoxHeightArr[minIndex] = BoxHeightArr[minIndex] + ccontent[i].offsetHeight;
}
}
;}

//获取第一行图片高度最小的索引值
function getminheightLocation(BoxHeightArr, minHeight){
for(var i in BoxHeightArr){
if(BoxHeightArr[i] == minHeight){
 return i;
}
}
}

//获取所有box
function getChildElement(parent, content){
contentArr = parent.getElementsByClassName(content);
return contentArr;
}

效果图:

纯js实现瀑布流布局及ajax动态新增数据

0
投稿

猜你喜欢

  • 我们经常会用到表格数据,在做表格的时候,一般都喜欢隔行变色,使表格表现数据的时候非常的清晰。如图,我设计的一个表格表现的样式:在网上找到一个
  • Sql Server 中一个非常强大的日期格式化函数: 获得当前系统时间,GETDATE(): 2008年01月08日 星期二 14:59
  • IIf 函数   根据表达式的值,来返回两部分中的其中一个。语法IIf(expr, truepart, fal
  • global 属性返回 Boolean 值,指出正则表达式使用的global 标志 (g) 的状态。默认值为 false。只读。rgExp.
  •  用ASP编写虚拟社区、网上购物等程序时,Application和Session对象具有举足轻重的作用,能够灵活合理地运用这两个对
  • 前言:书终于完稿了,我也有了一些自己的时间,于是决定将书中讲到的一些比较常见的知识点整理出来,发在Blog里面。当然也不会完全发表出来,毕竟
  • 描述event代表事件的状态,例如触发event对象的元素、鼠标的位置及状态、按下的键等等。event对象只在事件发生的过程中才有效。eve
  • 网上有这样一道题目:一个字符串String=“adadfdfseffserfefsefseetsdg”,找出里面出现次数最多的字母和出现的次
  • 也许你听说过Hibernate的大名,但可能一直不了解它,也许你一直渴望使用它进行开发,那么本文正是你所需要的!在本文中,我向大家重点介绍H
  • 有空余的时候自己写了一下,代码没有进行很好的规整。如果发现bug请及时通告我,谢谢   主要功能:1、点击插入表情,可选
  • MySQL默认编码是latin1,因业务需要把它转到UTF8。1、导出数据导出表结构 mysqldump -d dataname >
  • 上文:栅格:从混乱到秩序Jacci Howard Bear 的英文原文:http://desktoppub.about.com/od/gri
  • 在我的上篇文章发出之后,我听到对“WEb2.0视觉风格”这个称谓的不认同声音。其实这并不出乎我的意料,因为,我在认真的开始思考“WEb2.0
  • 使用 Response.Redirect "aspxhome.asp" 转向方法的HTTP Status Code 为3
  • 用analyze进行处理,定期进行处理ANALYZE [LOCAL | NO_WRITE_TO_BINLOG] TABLE tb1_name
  • 之前在比赛的时候需要用Python实现灰色关联分析,从网上搜了下只有实现两个列之间的,于是我把它改写成了直接想Pandas中的计算工具直接计
  • 本文实例为大家分享了python抖音表白神器,供大家参考,具体内容如下# -*- coding: utf-8 -*-import sysfr
  •  在我们设计网页的时候,总会遇到一些不愉快的事情,最常见的莫过于在后台添加内容后才发现显示的页面被撑开,导致网页极度不美观。以前大
  • 斜角导航条看上去立体感比较强,但实现起来比较麻烦;这是前几天写的一个测试代码,实现时,本来想用简单的图片加负数来实现;但GIF图片对半透明的
  • PHP mysqli_stmt_init() 函数初始化声明并返回 mysqli_stmt_prepare() 使用的对象:<?php
手机版 网络编程 asp之家 www.aspxhome.com