八月了,时间过得可真快。不知道自己现在的状态是什么,有点不太明确自己的定位。也算是个大二的学生了,可是一直都是一颗大一的心。要学的东西还有很多呢,加油!
看到让写“瀑布流”的时候,自己还是很懵的,因为不太清楚它的具体操作。只是所谓的“瀑布流”其实还是比较常见的,比如百度图片时,就是以瀑布流的形式呈现的。所以形式熟悉,操作的关键呢,就是在图片的布局,和上下图片的衔接上。这两大部分,一个是关于宽度的操作,一个是关于高度的操作。在html和css部分都是很简单的,主要的操作就在js上。
思路:
第一步:确定图片的每行图片的个数,及图片的居中显示
思路:一个大的div包括了所有的图片div,图片分为外层的div ->'box',内层的图片div ->'img_box'。通过传参传入父级div ->'container',在经过for循环判断id 得到 子级的每张图片的div 为'box',将其放入数组。然后通过数组元素计算出每张图片的大小,再得到屏幕的大小,再而算出来每行可以放多少张图片。为了避免图片在窗口大小变化时,每行的个数也发生变化,从而要固定每行的图片张数。
第二步:确定图片的高度,以及每行图片的衔接摆放
思路:将第一行图片的高度放入数组,然后找出其中高度最小的图片,再调用方法通过for循环找到最小高度的图片的下标,然后让下一行的第一张图片放在上一行高度最低的那张图片下面,进行定位,再改变图片的高度(上一张+下一张),以及相对于 距离左边的距离,并改变最小下标的高度,在通过数组‘box’的改变(i++)进行下一次循环。以实现图片的无限循环排放。
下面来介绍一下瀑布流的操作:
1.将图片添加到整个大的div -> 'container'中,每张图片都放入一个div ->'box'中,然后设置图片的css样式。
图片在html文件中的布局
<div id="container">
<div class="box">
<div class="img_box">
<img src="image/13.jpg">
</div>
</div>
<div class="box">
<div class="img_box">
<img src="image/14.jpg">
</div>
</div>
</div>
图片的css样式
*{
padding: 0;
margin: 0;
}
#container{
position: relative;
}
.img_box{
border: 1px solid #cccccc;
border-radius: 5px;
padding: 5px;
box-shadow: 0 0 5px #cccccc;
}
.box{
padding: 5px;
float: left;
}
.img_box img{
width: 200px;
height: auto;
}
2. 将承载每张图片的div ->'box',放入数组中,为接下来得到每张图片的宽度,图片的高度,距离左边的距离做好铺垫。
//得到所有的‘box’数组
function getElementboxs(parent,content) {
var getboxsArr = [];//得到所有的‘box’放入数组
var allcontent = parent.getElementsByTagName("*");
for(var i =0;i<allcontent.length;i++){
if(allcontent[i].className === content){
getboxsArr.push(allcontent[i]);
}
}
return getboxsArr;
}
3. 得到每张图片的宽度(每张图片的宽度一样),以及屏幕的宽度,就可以得到屏幕一行可以放多少张图片。并固定每行可以放置的图片个数,并居中放置。放置浏览器的窗口大小变化,影响每行图片的摆放。
function imageLocation(parent,content){
var cparent = document.getElementById(parent);//通过父级元素得到子级
var ccontent = getElementboxs(cparent,content);//得到所有的‘box’,为数组
var imgWidth = ccontent[0].offsetWidth; //每张图片的宽度
var screenWidth = document.documentElement.clientWidth;//得到屏幕的宽度
var num = Math.floor(screenWidth/imgWidth); //得到每行可以放下图片的个数,取整数
cparent.style.cssText = "width:"+ imgWidth * num +"px;margin:0 auto";
//固定每行图片个数,并居中显示
}
4.通过数组得到每张图片的高度,找到高度最低的图片的下标,实现每张图片的绝对定位,设置其距离顶部的高度为最低的图片高度,其离左边的距离是最低的图片离左边的距离,给每次筛选出来的图片定位。
将每张图片的高度加入数组,并给每次筛选出来的图片定位。
var imgHeightArr = [];//将第一行的图片的高度放入数组
for(var i = 0;i<ccontent.length;i++){
if(i<num){
imgHeightArr[i] = ccontent[i].offsetHeight;
}
else{
var minHeigthImg = Math.min.apply(null,imgHeightArr);//得到高度最小的图片
var minHeightIndex =getminHeightIndex(imgHeightArr,minHeigthImg);
//得到最小高度的下标
ccontent[i].style.position = "absolute";//固定图片的位置,绝对定位
ccontent[i].style.top= minHeigthImg +"px";
//设置图片距顶部的高度,刚好是高度最小的那张图片的位置
ccontent[i].style.left = ccontent[minHeightIndex].offsetLeft + "px";
//设置图片距离左边的距离,则是最低图片的下标距离最左边的距离
imgHeightArr[minHeightIndex] = imgHeightArr[minHeightIndex] + ccontent[i].offsetHeight;
//图片放好后,改变最低图片的高度,加上新放上去的,其成为最高的图片,进入下次循环
}
循环找到高度最低的图片的下标
function getminHeightIndex(imgHeightArr,minHeightImg) {
for(var i in imgHeightArr){
if(imgHeightArr[i] === minHeightImg){
return i;
}
}
}
基本的瀑布流就实现了,我们来看下效果图:
为了达到美观的效果,还模仿着做了一个滚动条无限滚动鼠标都会显示图片的效果。就像百度网页的图片是一样的效果,感觉图片时刷不完的。
实现无限加载的关键:
找到最后一张图片的距离顶部的高度,以及滚动条的高度(会随着鼠标滚动,数值不断变化,会有隐藏部分),和屏幕的高度。如果距离顶部的高度<(滚动条高度+屏幕高度)
,则在for循环进行添加图片节点,追加节点添加,与html文件中的嵌套相同(注意父节点与子节点的改变),来实现图片的不断添加,无限滚动。由于真正的网页图片由服务器提供,我们如果要实现图片的添加,就要模拟json字符串来增加图片。
那现在来看看代码的实现:
1.找到该进行加载的高度,进行循环的无限加载
function checkTop() {
var parents = document.getElementById("container");
var contents = getElementboxs(parents,"box");//通过父级元素找到所有的‘box’的数组
var lastImagetop = contents[contents.length - 1].offsetTop;
//得到最后一张图片距顶部的高度
var scrollTop = document.documentElement.scrollTop||document.body.scrollTop;
//得到滚动条的高度(包括隐藏部分)
var screenHeight = document.documentElement.clientHeight||document.body.clientHeight;
//得到屏幕的高度
if(lastImagetop < screenHeight + scrollTop){
return true;
}
}
2.找到要加载的高度,开始循环进行无限加载,重点是节点的添加与html文件中的嵌套相同。
window.onload = function () {
imageLocation("container","box");
var ImageData = { //模拟json字符串,获取图片数据
"data":[{"src":"38.jpg"},{"src":"13.jpg"},{"src":"22.jpg"},{"src":"23.jpg"},{"src":"27.jpg"},
{"src":"40.jpg"},{"src":"34.jpg"},{"src":"33.jpg"},{"src":"32.jpg"},{"src":"31.jpg"},{"src":"30.jpg"}]};
//添加节点以至于可以无限浏览。循环中操作。
(div层层嵌套注意父节点与子节点的改变)
window.onscroll = function () { //监控滚动条
if(checkTop()){
var container = document.getElementById("container"); //先找到父元素
for(var i =0 ;i<ImageData.data.length;i++){ //循环json字符串
var box = document.createElement("div"); //创建子元素节点(第一层div)
box.className = "box"; //设置统一的class,以识别其添加的层次
container.appendChild(box); //向父级元素中追加创建的新节点
var imgbox = document.createElement("div");//(第二层div)
imgbox.className = "img_box";
box.appendChild(imgbox);
var img = document.createElement("img"); //(第三层内包含图片)
img.src = "image/"+ImageData.data[i].src;
imgbox.appendChild(img);
}
imageLocation("container","box");
//每次加载过后要进行高度排序,d要重新进行循环放置图片
}
}
}
来看下实现无限加载后的效果图:
就结束啦,是个小收获,算是学习的js的综合应用吧。