多栏布局与JS实现瀑布流

css3属性之多栏布局与JS实现瀑布流

   背景:之前打算自己总结一下flex布局的知识点,发现自己无从下手,原因在何处:我反思了一下,其实原因很简单,使用的次数少,更多的时间使用了百分比,浮动和定位解决。这也就显示出了博客和笔记的区别,自己平时做笔记,更多的记录,而不是总结,其实自己没有熟练掌握。

  有的时候甚至出现了这样的笔记:

我打算坚持写博客,不论自己总结有多么差劲,也要坚持写,哪怕几年后我看到以前的笔记,自己会偷偷笑出声。想想原来大一时的技术还是那样的稚嫩啊。

Css3多列

  1)首提的兼容性问题:IE10以及opera支持多列(column),chrome需要-webkit-前缀,Firefox需要-moz-的前缀,Ie9以及更早版本就不支持多列了。你可以使用这个工具,很方便的查看你的浏览器内核以及版本信息http://ie.icoa.cn/

  2)Css3多列属性:css3多列主要是五个属性

column-count   <规定元素被分隔的列数>

column-gap    <规定列与列之间的间隔>

column-rule      <列之间的宽度、样式、颜色>

column-width        <列的宽度>

column-span         <元素应该横跨的列数>

 注意:在设置column-width宽度时,同时设置盒子的width,否则宽度默认为100%,每栏宽度按栏数平均分;盒子每栏宽度必须大于等于column-width设定的值,否则就会减少栏数来增加每栏宽度

css3多列和JS实现瀑布流

 给自己安利一波吧,看到网上很多瀑布流的效果,哇,简直棒极了有没有;于是我迫不及待的打开vpn,打开了pinterest的官网。

自己也梳理梳理逻辑:<在写js代码之前,一定要先搞清逻辑,再动手写代码>

我们都不陌生瀑布流是同宽的,但是高度不一,js主要的工作就是根据高度来进行布局,

1)当一行排满后,准备排第二行的时候,把第一个图片放到上一行图片高度最小处,以此类推,

另外有一点就是自动加载,这里我做一个条件来判断是否加载,

2)当最后一个的元素距离网页顶部的高度(offsetTop)+ 这个元素高度的一半 < 垂直方向上滚轮的量(scrollTop) + 网页可见区域的高 时:

我们就加载图片(这里我没有用ajax请求,我用了一个json数组来模拟json数据)

要搞清楚offsetTop、scrollTop、clientHeight这些的具体含义:可以参考前辈的博客

梳理完逻辑,让我们动手写代码吧:

html比较简单,这里图片我用了placehold的图片占位符,如果你没有很好的素材,这也许是个不错的选择

<body>
<div class="main clearfix" id="main">
    <div class="box">
        <div class="pic"><img src="http://placehold.it/200x300"/></div>
    </div>
    <div class="box">
        <div class="pic"><img src="http://placehold.it/200x300"/></div>
    </div>
    <div class="box">
        <div class="pic"><img src="http://placehold.it/200x300"/></div>
    </div>
    <div class="box">
        <div class="pic"><img src="http://placehold.it/200x200"/></div>
    </div>
    <div class="box">
        <div class="pic"><img src="http://placehold.it/200x200"/></div>
    </div>
    <div class="box">
        <div class="pic"><img src="http://placehold.it/200x300"/></div>
    </div>
    <div class="box">
        <div class="pic"><img src="http://placehold.it/200x300"/></div>
    </div>
    <div class="box">
        <div class="pic"><img src="http://placehold.it/200x300"/></div>
    </div>
    <div class="box">
        <div class="pic"><img src="http://placehold.it/200x300"/></div>
    </div>
    <div class="box">
        <div class="pic"><img src="http://placehold.it/200x150"/></div>
    </div>
    <div class="box">
        <div class="pic"><img src="http://placehold.it/200x200"/></div>
    </div>
    <div class="box">
        <div class="pic"><img src="http://placehold.it/200x300"/></div>
    </div>
    <div class="box">
        <div class="pic"><img src="http://placehold.it/200x200"/></div>
    </div>
    <div class="box">
        <div class="pic"><img src="http://placehold.it/200x300"/></div>
    </div>
    <div class="box">
        <div class="pic"><img src="http://placehold.it/200x300"/></div>
    </div>
    <div class="box">
        <div class="pic"><img src="http://placehold.it/200x200"/></div>
    </div>
    <div class="box">
        <div class="pic"><img src="http://placehold.it/200x300"/></div>
    </div>
    <div class="box">
        <div class="pic"><img src="http://placehold.it/200x300"/></div>
    </div>
    <div class="box">
        <div class="pic"><img src="http://placehold.it/200x300"/></div>
    </div>
    <div class="box">
        <div class="pic"><img src="http://placehold.it/200x300"/></div>
    </div>
    <div class="box">
        <div class="pic"><img src="http://placehold.it/200x300"/></div>
    </div>
    <div class="box">
        <div class="pic"><img src="http://placehold.it/200x300"/></div>
    </div>
    <div class="box">
        <div class="pic"><img src="http://placehold.it/200x300"/></div>
    </div>
    <div class="box">
        <div class="pic"><img src="http://placehold.it/200x100"/></div>
    </div>
    <div class="box">
        <div class="pic"><img src="http://placehold.it/200x300"/></div>
    </div>
    <div class="box">
        <div class="pic"><img src="http://placehold.it/200x150"/></div>
    </div>
    <div class="box">
        <div class="pic"><img src="http://placehold.it/200x300"/></div>
    </div>
    <div class="box">
        <div class="pic"><img src="http://placehold.it/200x200"/></div>
    </div>
    <div class="box">
        <div class="pic"><img src="http://placehold.it/200x300"/></div>
    </div>
</div>

css用了多列的column-width和column-gap属性

* {
            margin: 0;
            padding: 0;
        }

        .clearfix:after,
        .clearfix:before {
            content: "";
            display: table;
        }

        .clearfix:after {
            clear: both;
        }

        .main {
            position: relative;
            -webkit-column-width: 210px;
            -webkit-column-gap: 5px;
            -moz-column-gap: 5px;
        }

        .box {
            float: left;
            padding: 15px 0 0 15px;
        }

        .box .pic {
            width: 200px;
            height: auto;
            padding: 10px;
            border-radius: 10px;
            box-shadow: 0px 0 5px #ccc;
        }

        .box .pic img {
            display: block;
            width: 100%;
        }

梳理完了逻辑,该动手写js了

 window.onload = function () {

            waterfall('main', 'box');

            var ImgJson = {
                'data': [
                    {'src': 'http://placehold.it/200x300'}

                ]
            };

            //监听scroll事件
            window.onscroll = function () {
                var isPosting = false;
                if (checkScrollSlide('main', 'box') && !isPosting) {
                    var oParent = document.getElementById('main');
                    for (var i in ImgJson.data) {
                        var oBox = document.createElement('div');
                        oBox.className = 'box';
                        oBox.innerHTML = '<div class="pic"><img src="' + ImgJson.data[i].src + '"></div>';
                        oParent.appendChild(oBox);
                    }
                    isPosting = false;
                    waterfall('main', 'box');
                }
            }
        };

        function waterfall(parent, clsName) {
            //获取元素
            var oParent = document.getElementById(parent);
            //获取所有box
            var aBoxArr = oParent.getElementsByClassName(clsName);
            //单个box的宽度
            var iBoxw = aBoxArr[0].offsetWidth;
            //列数
            var cols = Math.floor(document.documentElement.clientWidth / iBoxw);
            oParent.style.cssText = 'width:' + iBoxw * (cols + 1) + 'px;margin:0 auto;';

            //储存所有高度
            var hArr = [];
            for (var i = 0; i < aBoxArr.length; i++) {
                if (i < cols) {
                    hArr[i] = aBoxArr[i].offsetHeight;
                } else {
                    //获取hArr的最小值
                    var minH = Math.min.apply(null, hArr);
                    //hArr最小值索引index
                    var minHIndex = getMinHIndex(hArr, minH);
                    aBoxArr[i].style.cssText = 'position:absolute;top:' + minH + 'px;left:' + aBoxArr[minHIndex].offsetLeft + 'px';

                    //添加元素之后更新hArr
                    hArr[minHIndex] += aBoxArr[i].offsetHeight;
                }
            }
        }

        //获取最小索引值
        function getMinHIndex(arr, val) {
            for (var i in arr) {
                if (arr[i] == val) {
                    return i;
                }
            }
        }

        //检查是否满足加载数据的条件
        function checkScrollSlide(parent, clsName) {
            var oParent = document.getElementById(parent);
            var aBoxArr = oParent.getElementsByClassName(clsName);
            //最后一个box元素的offsetTop+高度的一半
            var lastBoxH = aBoxArr[aBoxArr.length - 1].offsetTop + aBoxArr[aBoxArr.length - 1].offsetHeight / 2;

            var scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
            var height = document.documentElement.clientHeight || document.body.clientHeight;
            return lastBoxH < scrollTop + height;
        }

  最后走一波效果图

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏一个爱瞎折腾的程序猿

js实用方法记录-指不定哪天就会用到的js方法

341
来自专栏菩提树下的杨过

scrollTop与offsetTop研究

虽然我是做后台出身的,但最近心血来潮越来越关注前台技术了^_^,前二天看了“司徒正美”先生的图片无缝滚动分析后,对于scrollTop和offsetTop这二个...

1825
来自专栏前端杂货铺

canvas实现拖动页面时显示窗口视频

简介   当前主流的视频网站目前有不少新鲜好玩的功能,最明显的莫过于小视频的显示--当视频不在当前视口范围 时,会在右下角用一个小窗口来显示当前的视频,而且可以...

3705
来自专栏HTML5学堂

scrollLeft等属性介绍

HTML5学堂:在平日中书写滚动类特效时,为了提升代码的扩展性,通常会使用变量替换掉常量,此时会经常用到scrollLeft、offsetWidth、clien...

2595
来自专栏vue学习

偏移量、客户区大小、视口大小、滚动大小、确定元素大小

1、偏移量 先讲几个偏移量属性: offsetHeight:元素在垂直方向上占用的空间大小;相当于border-top+padding-top+height...

732
来自专栏阮一峰的网络日志

用Javascript获取页面元素的位置

制作网页的过程中,你有时候需要知道某个元素在网页上的确切位置。 下面的教程总结了Javascript在网页定位方面的相关知识。 一、网页的大小和浏览器窗口的大小...

4077
来自专栏Android开发小工

JS动画效果

相信大家在很多门户网站上都可以看到动画的交互效果,通过这些动画生动地体现了我们在网页上的交互效果,现在我们就来学习一下这些动画效果的分解动作吧。作为学习了网页设...

1627
来自专栏技术博文

js获取div编辑框,textarea,input text的光标位置,兼容FF和IE

<h<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3....

3456
来自专栏超然的博客

document.body.scrollTop与document.documentElement.scrollTop兼容

  这两天在写一个JS的网页右键菜单,在实现菜单定位的时候发现了这个问题:chrome居然不认识document.documentElement.scrollT...

802
来自专栏娱乐心理测试

小程序------日历效果

1313

扫码关注云+社区