javascriptweb前端javascript首页投稿(暂停使用,暂停投稿)

JS 实现瀑布流

2016-09-14  本文已影响2025人  ghwaphon

在极客学院下载的 JS 基础视屏中提到了瀑布流效果,花了一下午的时间去学习,到现在终于也算有所理解了,自己也动手实现了这么一个效果,来看一下吧。

demo.gif

我个人感觉这个效果还是比较好看的,下面我们就来看看怎么实现吧。

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 , 所以该方法肯定要实现一个定位功能?给谁定位?当然是给图片定位!

在以上代码中我们用到了 两个自定义的方法,分别是 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 ,就意味着,我们必须要能够满足能够滑动的事件,说的再通俗一点,就是初始的图片要高于当前浏览器可见的高度。

好了,瀑布流的效果就介绍到这里,大家中秋快乐。

上一篇下一篇

猜你喜欢

热点阅读