首页 > 代码库 > javascript瀑布流效果

javascript瀑布流效果

javascript瀑布流效果

    其实javascript瀑布流 前几年都已经很流行了(特别是美丽说,蘑菇街),最近看到网上有人问这个瀑布流效果,所以自己有空的时候就研究了下,其实也是研究别人的代码,研究了下别人写的思路,所以有了一个自己的版本代码。下面来讲讲瀑布流的思路吧!

    思路:1.先计算当前屏幕或者当前容器最多能容纳几列瀑布,其计算方法为 maxCol =  "Math.floor(屏幕可见区域宽度或者容器可视区宽度 / (格子宽度+间距))";

            2. 如果当前的容器没有定宽度话,可以设置容器的宽度为:width = 列数* (格子宽度+间距) – 间距. 因为 当容器的宽度计算出来之后再显示,否则会造成页面宽度的抖动,影响体验。计算方法可以理解如下:

上面列数为 6列 ,5个间距,因为最右边间距不算的,所以容器的计算方法为:width = 列数 * (格子宽度+间距) - 间距。

         3.   排序: 目前支持2种插入方式: 1. 计算出每列最短的高度,依次插入。2. 每列是按顺序插入进去。

 下面还是看看JSFiddler效果吧!

  亲,请点击我看效果!

组件配置项如下:

   container
  ‘‘,    瀑布流容器 必填项
 columnWidth ‘204‘,     列宽度 必填
 columnClassName ‘columnCls‘,        // 列类名  必填
 columnSpace 10,                 // 列间距
 cellCls  ‘.cell‘,            // 每一列单元格class类名
isLoadTarget‘img‘,              // 要加载目标选择器 默认为img
isAutoLoadHeight true,               // 是否需要自动计算图片的高度
fadeIn

true,               // 是否渐显加载 默认为true


 speed 500,                // 渐显速率 默认为500(毫秒)
 type 1,                  // 插入方式 1为插入最短那列,2 为按顺序插入
 diff 100                 // 滚动时, 当最小高度的列超过在屏幕高度+已滚动高度+diff时, 会去加载更多数据

代码分析如下:

 1. 初始化方法:_init(); 1. 创建列,2. 渲染页面内容。3.处理窗口滚动及缩小窗口事件。如下图所示:

 

 

下面是所有的JS代码如下:

/** * JS瀑布流布局 * @ver 1.0 * @param {options,callback} 对象配置项 回调 **/  function WaterFall(options,callback) {    var self = this;    self.options = $.extend({},defaults,options || {});    this.cache = {        $columns   : 0,   // 所有的列        loadIndex  : 0    // 加载的次数    };    self.callback = callback;    this._init(); } $.extend(WaterFall.prototype,{        /*     * 代码初始化 {创建列操作 对已存在的元素排序 窗口缩放或滚动事件}     * @method _init {private}     */    _init: function(){        var self = this,            cache = self.cache;        var cfg = self.options;        if(cfg.container == ‘‘) {return;}        cache.$columns = self._createColumn();        //重排已存在元素时强制不渐显        self.render($(cfg.container).find(cfg.cellCls),false);                var scrollTime,            resizeTime;        $(window).unbind(‘scroll‘).bind(‘scroll‘,function(){            scrollTime && clearTimeout(scrollTime);            scrollTime = setTimeout(function(){                self._onScroll();            },100);        });        $(window).unbind(‘resize‘).bind(‘resize‘,function(){            resizeTime && clearTimeout(resizeTime);            resizeTime = setTimeout(function(){                self._onResize();            },100);        });    },    /*     * 创建列     * @method _createColumn {private}     */    _createColumn: function(){        var self = this,            cfg = self.options;        var columnLen = self._calculateColumns();        var html = "";        for(var i = 0; i < columnLen; i++) {            html+= ‘<div class="‘+cfg.columnClassName+‘" style="width:‘+cfg.columnWidth+‘px;display:inline-block;vertical-align:top;*display:inline;zoom:1;margin-left:‘+cfg.columnSpace/2+‘px;margin-right:‘+cfg.columnSpace/2+‘px;overflow:hidden"></div>‘        }        $(cfg.container).prepend(html);        return $(‘.‘+cfg.columnClassName,cfg.container);//列集合    },    /*     * 共有多少列     * 计算方法: maxCol = Math.floor(屏幕可见区域的宽度或者父容器的宽度/(格子宽度+间距));     * @method _calculateColumns {private}     */    _calculateColumns: function(){        var self = this,            cfg = self.options;        var num = Math.floor($(cfg.container).outerWidth()/(cfg.columnWidth *1 + cfg.columnSpace*1));        if(num < 1){num = 1;}        return num;    },    /*     * 渲染内容     * @param {elements flag} 所有.cell类元素  boolean     */    render: function(elements,flag){        var self = this,            cfg = self.options,            cache = self.cache;        if($(elements).length <= 0) {return;}        $(elements).each(function(index,$this){            if(!cfg.isAutoLoadHeight) { //如果给出了图片高度 不需要自动计算高度                if(cfg.type == 1) {                    self._byShortInsert($(this),cfg.fadeIn && flag);//插入最短那列                }else if(cfg.type == 2){                    self._byOrderInsert($(this),cfg.fadeIn && flag);// 按顺序插入                }            }else {                self._renderHTML($(this),flag,index);            }        });    },    _renderHTML: function(elem,flag,index){        var self = this,            cfg = self.options;        if($(elem)[0].nodeName.toLowerCase()==‘img‘|| $(elem).find(cfg.isLoadTarget).length > 0) {            var image = new Image();            var src = http://www.mamicode.com/$(elem)[0].nodeName.toLowerCase()==‘img‘ ? $(elem).attr(‘src‘):$(elem).find(cfg.isLoadTarget).attr(‘src‘);            //图片加载后才能自动计算出尺寸 除IE以外的浏览器            image.onload = function(){                image.onreadystatechange=null;                if(cfg.type == 1) {                    self._byShortInsert(elem,cfg.fadeIn && flag);//插入最短那列                }else if(cfg.type == 2){                    self._byOrderInsert(elem,cfg.fadeIn && flag,index);// 按顺序插入                }                image = null;            };            // 针对IE私有 onreadystatechange            image.onreadystatechange = function(){                 if(image.readyState == "complete"){                     image.onload=null;                     if(cfg.type==1){                         self._byShortInsert(elem,cfg.fadeIn && flag);//插入最短那列                     }else if(cfg.type == 2){                        self._byOrderInsert(elem,cfg.fadeIn && flag);// 按顺序插入                     }                     image=null;                 }            }            image.src=src;        }else {            if(cfg.type == 1) {                self._byShortInsert(elem,cfg.fadeIn && flag);//插入最短那列            }else if(cfg.type == 2){                self._byOrderInsert(elem,cfg.fadeIn && flag,index);// 按顺序插入            }        }    },    /*     * 按最短的那列插入     * @method _byShortInsert     * @param {elem flag}     */    _byShortInsert: function(elem,flag){        var self = this,            cfg = self.options,            cache = self.cache;        var $columns = cache.$columns;        if(flag) { //渐显            var calculateLowest = self._calculateLowest();            $(elem).css(‘opacity‘,0).appendTo($columns.eq(calculateLowest)).fadeTo(cfg.speed,1);        }else {            //不渐显            var calculateLowest = self._calculateLowest();            $(elem).appendTo($columns.eq(calculateLowest));        }    },    /*     * 计算最短的那列的索引     * @method _calculateLowest {private}     * @return 返回列最短的索引 index     */    _calculateLowest: function(){        var self = this,            cache = self.cache;        var $columns = cache.$columns,            index = 0;        // 获取第一列的高度 循环 依次对比 然后返回最小的高度        var firstHeight = $columns.eq(0).outerHeight();        for(var i = 0; i < $columns.length; i++){            var curHeight = $($columns[i]).outerHeight();            if(curHeight < firstHeight) {                firstHeight = curHeight;                index = i;            }        }        return index;    },    /*     * 按顺序插入     * @method _byOrderInsert {private}     */    _byOrderInsert: function(elem,flag,index){        var self = this,            cfg = self.options;        var columnLen = self._calculateColumns(),            $columns = cache.$columns;        if(flag) { //渐显            $(elem).css(‘opacity‘,0).appendTo($columns.eq(index % columnLen)).fadeTo(cfg.speed,1);        }else { //不渐显            $(elem).appendTo($columns.eq(index % columnLen));        }    },    /*     * 滚动到底部时 再进行加载     */    _onScroll: function(){        var self = this,            cfg = self.options,            cache = self.cache;        var lowestIndex = self._calculateLowest(),            $lowest_column = cache.$columns.eq(lowestIndex);        //最短列底部距离浏览器窗口顶部的距离        var colHeight = $lowest_column.offset().top + $lowest_column.outerHeight();        // 当最小高度的列超过在屏幕高度+已滚动高度+diff时, 会去加载更多数据        if(cfg.diff + $(window).scrollTop() + $(window).outerHeight() >= colHeight) {            cache.loadIndex++;            if(self.callback && $.isFunction(self.callback)){                self.callback(cache.loadIndex);                var curHtml = self.callback(cache.loadIndex);                self.render(curHtml,true);            }         }    },    /*     * 窗口缩放时候 重新排序     */    _onResize: function(){        var self = this,            cfg = self.options,            cache = self.cache;        var num = self._calculateColumns();        // 如果列数没有变 返回        if(num == cache.$columns.length) {            return;        }        var $cells=$(cfg.container).find(cfg.cellCls);        cache.$columns.remove();        cache.$columns = self._createColumn();        self.render($cells,false);    } }); var defaults = {    container            :      ‘‘,                 // 需要加载的容器 (必填)    columnWidth          :      ‘204‘,              // 列宽    columnClassName      :      ‘columnCls‘,        // 列类名    columnSpace          :      10,                 // 列间距    cellCls              :      ‘.cell‘,            // 每一列单元格class类名    isLoadTarget         :      ‘img‘,              // 要加载目标选择器 默认为img    isAutoLoadHeight     :      true,               // 是否需要自动计算图片的高度    fadeIn               :      true,               // 是否渐显加载 默认为true    speed                :      500,                // 渐显速率 默认为500(毫秒)    type                 :      1,                  // 插入方式 1为插入最短那列,2 为按顺序插入    diff                 :      100                 // 滚动时, 当最小高度的列超过在屏幕高度+已滚动高度+diff时, 会去加载更多数据. };

demo下载: