在极客学院下载的 JS
基础视屏中提到了瀑布流效果,花了一下午的时间去学习,到现在终于也算有所理解了,自己也动手实现了这么一个效果,来看一下吧。
我个人感觉这个效果还是比较好看的,下面我们就来看看怎么实现吧。
HTML 代码
其实 HTML
的编码是极其简单的,我们去除重复的部分,来看看核心代码
<div id="container">
<div class="box">
<div class="box_img">
<img src="imgs/1.jpg">
</div>
</div>
</div>
其实在 container
内部不止一个 div
标签,这里是为了简单,所以将其他的代码都省略了。 这里为什么要设置双层 div
包含住 img
标签呢,这里是为了在后面的 JS
代码中设置 position
属性,到后面自然而然就明白了。
CSS 代码
* {
margin: 0px;
padding: 0px;
}
#container {
position: relative;
}
.box {
float: left;
padding: 15px 0 0 15px;
}
.box .box_img {
padding: 10px;
border: 1px solid #cccccc;
border-radius: 5px;
box-shadow: 0px 0px 6px #cccccc;
}
.box_img img {
width: 172px;
height: auto;
}
*
选择器的使用可以说是遭受非议的,有人认为它的杀伤力太大了,不可以轻易的使用,但是作为初学者的我来说,还是十分喜欢使用其去除外边距和内边距。 这里我们为了好看,也是为图片设置了内边距,边框和阴影属性,值得一提的是为了保持所有的图片具有共同的宽度,我们将其设置为统一的 172px
,为什么设置为 172px
呢?我随便设的,你可以自己指定,高度的话我们设置成 auto
, 建议不要自己指定,不然你还实现什么瀑布流啊?图片的高度宽度都相同,还有什么瀑布流可言,顺序排列不就可以了吗?
我刚开始看瀑布流教学视屏的时候,是非常开心的,为什么呢?因为 HTML
代码和 CSS
代码真的好少哦。可是看到 JS
代码就不开心了,真的好长。好了,不吐槽了,来看看 JS
代码吧。
JS 代码
由于 JS
代码过长,所以我们逐段来分析,下面来看第一段。
function location(parent, child) {
1 var vparent = document.getElementById(parent);
2 var childArray = getChild(vparent, child);
3 var imgWidth = childArray[0].offsetWidth;
4 var cols = Math.floor(document.documentElement.clientWidth / imgWidth); // 计算每行能容纳多少列
5 vparent.style.cssText = "width : " + imgWidth * cols + "px;margin:0 auto;";
6 var boxHeightArray = [];
7 for (var i = 0; i < childArray.length; i++) {
8 if (i < cols) {
9 boxHeightArray[i] = childArray[i].offsetHeight;
10 } else {
11 var minHeight = Math.min.apply(null, boxHeightArray);
12 var minIndex = getIndex(boxHeightArray, minHeight);
13 childArray[i].style.position = "absolute";
14 childArray[i].style.top = minHeight + "px";
15 childArray[i].style.left = childArray[minIndex].offsetLeft + "px";
16 boxHeightArray[minIndex] = boxHeightArray[minIndex] + childArray[i].offsetHeight;
}
}
}
分析一个函数之前,我们首先要知道这个函数要实现的功能是什么?方法的名称叫做 location
, 所以该方法肯定要实现一个定位功能?给谁定位?当然是给图片定位!
- 第 1 - 3 行 : 获取当前 页面中 有多少张图片要展示并且获取图片的宽度。
- 第 4 行 : 计算当前一行能容纳多少列,也即一行能容纳多少个图片的展示。
- 第 5 行 : 将承载图片的父节点(其实这个时候就是
container
)设置为指定行,并且居中显示。 - 第 9 行 :将第一行图片的距离页面顶端的高度记录在一个数组中。
- 第 10 - 16 行 : 获取到第一行中高度最小的那张图片,将其在数组中的下标获取到,然后将下一行的图片放置到高度最小的图片的下方,更新高度值。其实这很像一个计数功能,当我们知道了一行放置多少图片之后,当我们放满了第一行,将高度值存放在数组中,从第二行开始,寻找数组中最小的那个值,然后将图片放在这一列,更新数组值。
在以上代码中我们用到了 两个自定义的方法,分别是 getChild()
和 getIndex()
,很容易理解,这里 只粘贴代码,就不在解释。
function getIndex(boxHeightArray, mingHeight) {
for (var i = 0; i < boxHeightArray.length; i++) {
if (boxHeightArray[i] == mingHeight) {
return i;
}
}
}
function getChild(parent, child) {
var contentArray = [];
var allcontent = parent.getElementsByTagName("*");
for (var i = 0; i < allcontent.length; i++) {
if (allcontent[i].className == child) {
contentArray.push(allcontent[i]);
}
}
return contentArray;
}
其实,通过上述方法,我们就实现了一个瀑布流效果,但是我们还想实现另一个效果,就是我们可以不断下拉,那么这个功能该怎么实现呢?既然想实现下拉动态加载效果,那么我们至少应该在什么时候开始动态加载吧?下面就来实现这么一个功能。
function check() {
var parent = document.getElementById("container");
var child = getChild(parent, "box");
var lastContentHeight = child[child.length - 1].offsetTop;
var scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
var pageHeight = document.documentElement.clientHeight || document.body.clientHeight;
if (lastContentHeight <= scrollTop + pageHeight) {
return true;
}
}
lastContentHeight
的值是最后一张图片到页面顶部的距离。 scrollTop
的值是当前正在显示的之前隐藏的部分。什么意思呢?举个例子来说,当我们进入一个网页,这个网页右垂直滚动条,那么刚进去时显示的肯定是网页的一部分,还有一部分处于隐藏状态,那么 scrollTop
的值就是从当前可见页面的底部开始从 0
计数的,往下拉,这个值就会递增。 pageHeight
的值就是当前可见页面的高度。那么最后的 if
条件判断是什么意思呢?这个判断语句的意思就是,当我们下拉到最后一张图片的顶部的时候,开始动态加载图片。好了,下面我们去看看加载图片的逻辑代码。
window.onscroll = function () {
var imgData = {
"data": [
{"src": "1.jpg"},
{"src": "2.jpg"},
{"src": "3.jpg"},
{"src": "4.jpg"},
{"src": "5.jpg"},
{"src": "6.jpg"},
{"src": "7.jpg"},
{"src": "8.jpg"}]
};
if (check()) {
var parent = document.getElementById("container");
for (var i = 0; i < imgData.data.length; i++) {
var box = document.createElement("div");
box.className = "box";
parent.appendChild(box);
var boximg = document.createElement("div");
boximg.className = "box_img";
box.appendChild(boximg);
var img = document.createElement("img");
img.src = "imgs/" + imgData.data[i].src;
boximg.appendChild(img);
}
location("container", "box");
}
}
其实这段逻辑代码反而好懂,意思就是当我们的页面滑动了,而且符合我们对动态加载图片的判断,即开始创建节点,和我们在 HTML
代码中创建的结构相同,这样我们才可以复用 CSS
代码。在底部别忘了调用 location()
函数,不然的话我们在新加载的图片中是无法看到瀑布流效果的。还有一个值得注意的地方,就是这里我们也看到了我们使用的是 window.scroll
,就意味着,我们必须要能够满足能够滑动的事件,说的再通俗一点,就是初始的图片要高于当前浏览器可见的高度。
好了,瀑布流的效果就介绍到这里,大家中秋快乐。
网友评论