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 = $(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私有 onreadystatechangeimage.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', // 要加載目標選擇器 默認為imgisAutoLoadHeight : true, // 是否需要自動計算圖片的高度fadeIn : true, // 是否漸顯加載 默認為truespeed : 500, // 漸顯速率 默認為500(毫秒)type : 1, // 插入方式 1為插入最短那列,2 為按順序插入diff : 100 // 滾動時, 當最小高度的列超過在屏幕高度+已滾動高度+diff時, 會去加載更多數據.};demo下載:
總結
以上是生活随笔為你收集整理的javascript瀑布流效果的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 《软件测试方法和技术》 读书笔记
- 下一篇: 查看windosw服务器序列号,型号