discuz门户频道实现瀑布流-Discuz教程下载

discuz门户频道实现瀑布流

开通本站Svip会员,全站资源免费下
门户里添加了一个图片频道,看现在的瀑布流这么火,于是想实现一下看看效果。

网上搜索到一个叫waterflow的瀑布流例子,研究了一下,发现要改造起来也不难,下面一步步来实现。

1.新建一个门户列表页瀑布流模板list_waterflow.htm,里面的内容可以先复制list.htm的贴进来。

因为是用ajax方式加载文章列表的,所以原来用loop循环的方式显示列表就可以抛弃了,列表html结构如下:

<div class="waterflow-container">
<div>
<div id="infscr-loading" style="display: block; ">
<img alt="Loading..." src="ajax-loader.gif">
<div>加载中...</div>
</div>
<div id="noshow" style="display: none; ">
<div>就这些了</div>
</div>
添加样式
  1. /*瀑布流样式*/
  2. .waterflow-container{position:relative;font-size:12px;border:1px solid #ccc;padding:0;margin:0;text-align:center;background-color:white;}
  3. .hide {display:none;}
  4. #infscr-loading{
  5. position: fixed;
  6. bottom: 40px;
  7. left: 50%;
  8. top:50%;
  9. width: 150px;
  10. text-align: center;
  11. margin-left: -75px;
  12. z-index: 99;
  13. }
  14. #infscr-loading div{
  15. display: block;
  16. padding: 5px 10px 5px 10px;
  17. background-color: #FAFAEF;
  18. border: 1px solid #AAA;
  19. border-radius: 6px;
  20. -moz-border-radius: 6px;
  21. -webkit-border-radius: 6px;
  22. -moz-box-shadow: 0 0 18px #999;
  23. -webkit-box-shadow: 0 0 18px #999;
  24. box-shadow: 0 0 18px #999;
  25. }
  26. #noshow {
  27. position: fixed;
  28. bottom: 40px;
  29. left: 50%;
  30. top:50%;
  31. width: 150px;
  32. text-align: center;
  33. margin-left: -75px;
  34. z-index: 99;
  35. }
  36. #noshow div{
  37. display: block;
  38. padding: 5px 10px 5px 10px;
  39. background-color: #FAFAEF;
  40. border: 1px solid #AAA;
  41. border-radius: 6px;
  42. -moz-border-radius: 6px;
  43. -webkit-border-radius: 6px;
  44. -moz-box-shadow: 0 0 18px #999;
  45. -webkit-box-shadow: 0 0 18px #999;
  46. box-shadow: 0 0 18px #999;
  47. }
复制代码
添加控制js:
  1. <script type="text/javascript" src="jquery.js"></script>
  2. <script type="text/javascript" src="jquery.windswaterflow.js"></script>
  3. <script type="text/javascript">
  4. var j = jQuery.noConflict();
  5. j(document).ready(function(){
  6.         j(".waterflow-container").windswaterflow({
  7.             itemSelector: '.box',
  8.             loadSelector: '#infscr-loading',
  9.             noSelector: '#noshow',
  10.             boxTemplate: '<div class="box hide"><a href="#"><div class="img"><img src="%img%" style="height:%height%px;" alt="" /></div></a><div class="title">%title%</div><div class="like btn">喜欢</div><div class="comments btn">评论</div></div>',
  11.             columnWidth: 210,
  12.             marginWidth: 24,
  13.             marginHeight: 16,
  14.             ajaxServer: 'portal.php?mod=list&catid='+{$catid}+'&waterflow=true',
  15.             boxParam: 'num',
  16.             pageParam: 'page',
  17.             maxPage: 0,
  18.             init: false,
  19.             initBoxNumber: 20,
  20.             scroll: true,
  21.             scrollBoxNumber: 10,
  22.             callback: function() {
  23.             }
  24.         });
  25. });
  26. </script>
复制代码
2.在source\module\portal\portal_list.php文件里,82行增加ajax提供数据的代码
  1. if(isset($_GET['waterflow'])){
  2. $wheresql = category_get_wheresql($cat);
  3. $list = category_get_list($cat,$wheresql,$page);
  4. echo json_encode($list['list']);
  5. die();
  6. }
复制代码
这样门户的瀑布流就基本实现了。
jquery.windswaterflow.js内容如下:
  1. (function($) {
  2.     $.fn.windswaterflow = function(options) {
  3.         //初始化状态
  4.         var _init = 0, _isminCols = false, _isnoShow = false;
  5.         var defaults = {
  6.             itemSelector: '',
  7.             loadSelector: '',
  8.             noSelector: '',
  9.             boxTemplate: '',
  10.             columnWidth: 240,
  11.             marginWidth: 14,
  12.             marginHeight: 16,
  13.             minCols: 3,
  14.             maxPage: 0,
  15.             align: 'center',
  16.             ajaxServer: '',
  17.             boxParam: '',
  18.             pageParam: 'page',
  19.             pageNumber: 1,
  20.             init: false,
  21.             initBoxNumber: 20,
  22.             scroll: false,
  23.             scrollBoxNumber: 10,
  24.             callback: null
  25.         };
  26.         //参数合并
  27.         var param = $.extend({}, defaults, options || {});
  28.         //如果没有元素和TPL则返回
  29.         if (param.itemSelector == '' || param.tplSelector == '') {
  30.             return;
  31.         }
  32.         if (param.loadSelector != '') {
  33.             //$(param.loadSelector).hide();
  34.         }
  35.         if (param.noSelector != '') {
  36.             $(param.noSelector).hide();
  37.         }
  38.         if ($(this).CSS('text-align') != undefined) {
  39.             param.align = $(this).css('text-align');
  40.         }
  41.         function _min(_arr) {
  42.             return Math.min.apply(Math, _arr);
  43.         };
  44.         function _max(_arr) {
  45.             return Math.max.apply(Math, _arr);
  46.         };

  47.         function findShortIndex(_arr) {
  48.             var index = 0, i;
  49.             for (i in _arr) {
  50.                 if (_arr[i] < _arr[index]) {
  51.                     index = i;
  52.                 }
  53.             }
  54.             return index;
  55.         };

  56.         function findLongIndex(_arr) {
  57.             var index = 0, i;
  58.             for (i in _arr) {
  59.                 if (_arr[i] > _arr[index]) {
  60.                     index = i;
  61.                 }
  62.             }
  63.             return index;
  64.         };
  65.         if (param.init) {
  66.             //如果有初始化,则清空原来的
  67.             $(this).html('');
  68.         }
  69.         //BOX个数
  70.         var _boxCount = $(param.itemSelector).length;
  71.         //每个BOX的宽度
  72.         var _boxWidth = param.columnWidth + param.marginWidth;
  73.         //包含层的宽度
  74.         var _containerWidth = $(this).width();
  75.         //计算出列数
  76.         var _showCols = Math.floor(_containerWidth / _boxWidth);
  77.         //得到居中后的左边padding
  78.         var _containerPadding = 0;
  79.         if (param.align == 'left') {
  80.             _containerPadding = 0;
  81.         }
  82.         else if (param.align == 'right') {
  83.             _containerPadding = _containerWidth % _boxWidth;
  84.         }
  85.         else {
  86.             _containerPadding = (_containerWidth % _boxWidth) / 2;
  87.         }
  88.         //如果小于最小列,则左边距为0
  89.         if (_showCols < param.minCols) {
  90.             _containerPadding = 0;
  91.             _showCols = param.minCols;
  92.             _isminCols = true;
  93.         }
  94.         //计算出行数
  95.         var _tpRows = $(param.itemSelector).length / _showCols;
  96.         var _showRows = Math.floor(_tpRows) == _tpRows ? _tpRows : _tpRows + 1;
  97.         //记录每行当前的高度
  98.         var _colsTopArr = [];
  99.         //初始化为0
  100.         for (var len = 0; len < _showCols; len++) {
  101.             _colsTopArr.push(0);
  102.         };
  103.         var selector = $(this).selector;
  104.         function setPosition(wrap, boxs, op) {
  105.             //临时 最短列序号,左位置值,上位置值
  106.             var _tpShortColIdx, _tpLeftPos, _tpTopPos, _tpLen = $(boxs).length;
  107.             if (op == "resize" || op == "init") {
  108.                 $(wrap).width()
  109.                 _isminCols = false;
  110.                 _containerWidth = $(wrap).width();
  111.                 _showCols = Math.floor(_containerWidth / _boxWidth);
  112.                 //得到居中后的左边padding
  113.                 if (param.align == 'left') {
  114.                     _containerPadding = 0;
  115.                 }
  116.                 else if (param.align == 'right') {
  117.                     _containerPadding = _containerWidth % _boxWidth;
  118.                 }
  119.                 else {
  120.                     _containerPadding = (_containerWidth % _boxWidth) / 2;
  121.                 }
  122.                 //如果小于最小列,则左边距为0
  123.                 if (_showCols < param.minCols) {
  124.                     _containerPadding = 0;
  125.                     _showCols = param.minCols;
  126.                     _isminCols = true;
  127.                 }

  128.                 //计算出行数
  129.                 _tpRows = $(boxs).length / _showCols;
  130.                 _showRows = Math.floor(_tpRows) == _tpRows ? _tpRows : _tpRows + 1;
  131.                 //初始化为0
  132.                 _colsTopArr.length = 0;
  133.                 for (var len = 0; len < _showCols; len++) {
  134.                     _colsTopArr.push(0);
  135.                 };
  136.             }
  137.             //在第一次加载时无高度的情况下
  138.             //chrome不能自已加载 $.browser.safari &&
  139.             if (op == null) {
  140.                 $(boxs).imagesLoaded(function() {
  141.                     $(boxs).each(function(index) {
  142.                         var _tpShortColIdx = index;
  143.                         if (_tpShortColIdx < _showCols && op != "add") {
  144.                             _tpLeftPos = _boxWidth * _tpShortColIdx + _containerPadding + "px";
  145.                             $(this).css({ "top": "0", "left": _tpLeftPos, "width": param.columnWidth + "px", "margin": "0" });
  146.                         }
  147.                         else {
  148.                             _tpShortColIdx = findShortIndex(_colsTopArr);
  149.                             _tpLeftPos = _boxWidth * _tpShortColIdx + _containerPadding + "px";
  150.                             _tpTopPos = _colsTopArr[_tpShortColIdx] + "px";
  151.                             $(this).css({ "top": _tpTopPos, "left": _tpLeftPos, "width": param.columnWidth + "px", "margin": "0" });
  152.                         }
  153.                         if (op == "add") {
  154.                             $(this).appendTo(wrap);
  155.                         }
  156.                         _colsTopArr[_tpShortColIdx] = _colsTopArr[_tpShortColIdx] + $(this).height() + param.marginHeight;

  157.                         //全部加入后增加外框
  158.                         if (index == _tpLen - 1) {
  159.                             $(wrap).height(_max(_colsTopArr) + "px");
  160.                             if (_isminCols) {
  161.                                 //设置以后回不去
  162.                                 //$(wrap).width((_boxWidth * _showCols + _containerPadding + param.marginWidth) + "px");
  163.                             }
  164.                             if (op == "add") {
  165.                                 if ($.browser.msie) {
  166.                                     $(".hide").animate({ opacity: 'show' }, 2000);
  167.                                 }
  168.                                 else {
  169.                                     $(".hide").animate({ opacity: 'show' }, 1000);
  170.                                 }
  171.                                 if (param.loadSelector != '') {
  172.                                     $(param.loadSelector).hide();
  173.                                 }
  174.                             }
  175.                             _SolStatus = 0;
  176.                         }

  177.                     });
  178.                 });
  179.             }
  180.             else {
  181.                 //将所有元素放到各自己的位置
  182.                 $(boxs).each(function(index) {
  183.                     var _tpShortColIdx = index;
  184.                     if (_tpShortColIdx < _showCols && op != "add") {
  185.                         _tpLeftPos = _boxWidth * _tpShortColIdx + _containerPadding + "px";
  186.                         $(this).css({ "top": "0", "left": _tpLeftPos, "width": param.columnWidth + "px", "margin": "0" });
  187.                     }
  188.                     else {
  189.                         _tpShortColIdx = findShortIndex(_colsTopArr);
  190.                         _tpLeftPos = _boxWidth * _tpShortColIdx + _containerPadding + "px";
  191.                         _tpTopPos = _colsTopArr[_tpShortColIdx] + "px";
  192.                         $(this).css({ "top": _tpTopPos, "left": _tpLeftPos, "width": param.columnWidth + "px", "margin": "0" });
  193.                     }
  194.                     if (op == "add" || op == "init") {
  195.                         $(this).appendTo(wrap);
  196.                     }
  197.                     _colsTopArr[_tpShortColIdx] = _colsTopArr[_tpShortColIdx] + $(this).height() + param.marginHeight; //parseInt($(this).css("marginTop")) * 2 + parseInt($(this).css("paddingTop")) + parseInt($(this).css("paddingBottom"));

  198.                     //全部加入后增加外框
  199.                     if (index == _tpLen - 1) {
  200.                         $(wrap).height(_max(_colsTopArr) + "px");
  201.                         if (_isminCols) {
  202.                             //设置以后回不去
  203.                             //$(wrap).width((_boxWidth * _showCols + _containerPadding + param.marginWidth) + "px");
  204.                         }
  205.                         if (op == "add") {
  206.                             if ($.browser.msie) {
  207.                                 $(".hide").animate({ opacity: 'show' }, 2000);
  208.                             }
  209.                             else {
  210.                                 $(".hide").animate({ opacity: 'show' }, 1000);
  211.                             }
  212.                         }
  213.                         else {
  214.                             $(".hide").animate({ opacity: 'show' }, 0);
  215.                         }
  216.                         if (param.loadSelector != '') {
  217.                             $(param.loadSelector).hide();
  218.                         }
  219.                         _SolStatus = 0;
  220.                         if (op == "add" || op == "init") {
  221.                             //每增加一次,页面加1
  222.                             param.pageNumber++;
  223.                         }
  224.                     }

  225.                 });
  226.             }
  227.             if (param.callback) {
  228.                 param.callback();
  229.             }
  230.         };

  231.         if (_boxCount > 0) {
  232.             setPosition(selector, param.itemSelector);
  233.         }
  234.         //初始化完成
  235.         _init = 1;

  236.         //添加元素进去(JSON)
  237.         function appendBox(data, op) {
  238.             var newBox = [], len = Number(data.length), idx = 0;
  239.             _boxCount += len;
  240.             $.each(data, function(i) {
  241.                 //通过imgReady获取图片高度
  242.                 imgReady(data[i].img, function() {
  243.                     //data[i].height = parseInt(this.height);   //?不知道高度值是否可靠
  244.                     //这里模版化BOX edit by winds 2012.4.26
  245.                     var temp = "";
  246.                     var matchs = param.boxTemplate.match(/\%[a-zA-Z0-9]+\%/gi);
  247.                     for (var j = 0, mlen = matchs.length; j < mlen; j++) {
  248.                         if (temp == "")
  249.                             temp = param.boxTemplate;
  250.                         var re_match = matchs[j].replace(/[\%\%]/gi, "");
  251.                         temp = temp.replace(matchs[j], data[i][re_match]).replace(/[\r\t\n]/g, "");
  252.                     }
  253.                     newBox.push(temp);
  254.                     //newBox.push('<div class="box hide"><a class="img" href="#"><img src="' + data[i].img + '" style="height:' + data[i].height + 'px;" alt="" /></a><span class="title">' + data[i].title + '</span></div>');
  255.                     idx++;
  256.                     if (idx == len) {
  257.                         setPosition(selector, newBox.join(''), op);
  258.                     }
  259.                 });
  260.             });
  261.         };

  262.         //需要初始每一次添加元素
  263.         if (param.init && param.ajaxServer != '' && param.boxParam != '' && parseInt(param.initBoxNumber) > 0) {
  264.             var postPara = {};
  265.             //初始化时参数为1
  266.             param.pageNumber = 1;
  267.             postPara[param.boxParam] = parseInt(param.initBoxNumber);
  268.             postPara[param.pageParam] = parseInt(param.pageNumber);
  269.             if (param.loadSelector != '') {
  270.                 $(param.loadSelector).show();
  271.             }
  272.             $.getJSON(param.ajaxServer, postPara, function(data) {
  273.                 if (data.length == 0) {
  274.                     //无数据返回时则显示无数据提示
  275.                     if (param.noSelector != '') {
  276.                         if (param.noSelector) {
  277.                             $(param.noSelector).fadeIn(1000).delay(2000).fadeOut(1000);
  278.                         }
  279.                     }
  280.                     if (param.loadSelector != '') {
  281.                         $(param.loadSelector).hide();
  282.                     }
  283.                     _isnoShow = true;
  284.                     _SolStatus = 0;
  285.                 }
  286.                 else {
  287.                     appendBox(data, 'init');
  288.                 }
  289.             });
  290.         }

  291.         //支持滚动加载
  292.         var _SolStatus = 0;
  293.         if (param.scroll && param.ajaxServer != '' && param.boxParam != '' && parseInt(param.scrollBoxNumber) > 0) {
  294.             $(window).scroll(function() {
  295.                 var scrollh = document.body.scrollHeight;
  296.                 var clienth = document.documentElement.clientHeight;
  297.                 var scrollt = document.documentElement.scrollTop + document.body.scrollTop;
  298.                 if (scrollt + clienth +100>= scrollh && _SolStatus == 0 && _init == 1 && !_isnoShow) {
  299.                     if ((param.maxPage == 0 || param.pageNumber <= param.maxPage)) {
  300.                         _SolStatus = 1;
  301.                         if (param.loadSelector != '') {
  302.                             $(param.loadSelector).show();
  303.                         }
  304.                         var postPara = {};
  305.                         postPara[param.boxParam] = parseInt(param.scrollBoxNumber);
  306.                         postPara[param.pageParam] = parseInt(param.pageNumber);
  307.                         setTimeout(function() {
  308.                             $.getJSON(param.ajaxServer, postPara, function(data) {
  309.                                 if (data.length == 0) {
  310.                                     //无数据返回时则显示无数据提示
  311.                                     if (param.noSelector != '') {
  312.                                         if (param.noSelector) {
  313.                                             $(param.noSelector).fadeIn(1000).delay(2500).fadeOut(1000);
  314.                                         }
  315.                                     }
  316.                                     if (param.loadSelector != '') {
  317.                                         $(param.loadSelector).hide();
  318.                                     }
  319.                                     _isnoShow = true;
  320.                                     _SolStatus = 0;
  321.                                 }
  322.                                 else {
  323.                                     appendBox(data, 'add');
  324.                                 }
  325.                             });
  326.                         }, 100);
  327.                     }
  328.                 }
  329.             });
  330.         }
  331.                

  332.         //支持RESIZE
  333.         var _ReStatus;
  334.         $(window).wresize(function() {
  335.             if (_ReStatus) {
  336.                 clearTimeout(_ReStatus);
  337.             }
  338.             _ReStatus = setTimeout(function() { setPosition(selector, param.itemSelector, "resize"); }, 200);
  339.         });
  340.     };

  341.     /**
  342.     * 图片头数据加载就绪事件 - 更快获取图片尺寸
  343.     * @version        2011.05.27
  344.     * @author        TangBin
  345.     * @see                http://www.planeart.cn/?p=1121
  346.     * @param        {String}        图片路径
  347.     * @param        {Function}        尺寸就绪
  348.     * @param        {Function}        加载完毕 (可选)
  349.     * @param        {Function}        加载错误 (可选)
  350.     * @example imgReady('http://www.google.com.hk/intl/zh-CN/images/logo_cn.png', function () {
  351.     alert('size ready: width=' + this.width + '; height=' + this.height);
  352.     });
  353.     */
  354.     var imgReady = (function() {
  355.         var list = [], intervalId = null,

  356.         // 用来执行队列
  357.             tick = function() {
  358.                 var i = 0;
  359.                 for (; i < list.length; i++) {
  360.                     list[i].end ? list.splice(i--, 1) : list[i]();
  361.                 };
  362.                 !list.length && stop();
  363.             },

  364.         // 停止所有定时器队列
  365.             stop = function() {
  366.                 clearInterval(intervalId);
  367.                 intervalId = null;
  368.             };

  369.         return function(url, ready, load, error) {
  370.             var onready, width, height, newWidth, newHeight,
  371.                         img = new Image();

  372.             img.src = url;

  373.             // 如果图片被缓存,则直接返回缓存数据
  374.             if (img.complete) {
  375.                 ready.call(img);
  376.                 load && load.call(img);
  377.                 return;
  378.             };

  379.             width = img.width;
  380.             height = img.height;

  381.             // 加载错误后的事件
  382.             img.onerror = function() {
  383.                 error && error.call(img);
  384.                 onready.end = true;
  385.                 img = img.onload = img.onerror = null;
  386.             };

  387.             // 图片尺寸就绪
  388.             onready = function() {
  389.                 newWidth = img.width;
  390.                 newHeight = img.height;
  391.                 if (newWidth !== width || newHeight !== height ||
  392.                 // 如果图片已经在其他地方加载可使用面积检测
  393.                                 newWidth * newHeight > 1024
  394.                         ) {
  395.                     ready.call(img);
  396.                     onready.end = true;
  397.                 };
  398.             };
  399.             onready();

  400.             // 完全加载完毕的事件
  401.             img.onload = function() {
  402.                 // onload在定时器时间差范围内可能比onready快
  403.                 // 这里进行检查并保证onready优先执行
  404.                 !onready.end && onready();

  405.                 load && load.call(img);

  406.                 // IE gif动画会循环执行onload,置空onload即可
  407.                 img = img.onload = img.onerror = null;
  408.             };

  409.             // 加入队列中定期执行
  410.             if (!onready.end) {
  411.                 list.push(onready);
  412.                 // 无论何时只允许出现一个定时器,减少浏览器性能损耗
  413.                 if (intervalId === null) intervalId = setInterval(tick, 40);
  414.             };
  415.         };
  416.     })();


  417.     //判断图片先加载完(网上找来的,masonry使用的这个)
  418.     $.fn.imagesLoaded = function(callback) {
  419.         var $this = this,
  420.             $images = $this.find('img').add($this.filter('img')),
  421.             len = $images.length,
  422.             blank = 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==',
  423.             loaded = [];

  424.         function triggerCallback() {
  425.             callback.call($this, $images);
  426.         }

  427.         function imgLoaded(event) {
  428.             var img = event.target;
  429.             if (img.src !== blank && $.inArray(img, loaded) === -1) {
  430.                 loaded.push(img);
  431.                 if (--len <= 0) {
  432.                     setTimeout(triggerCallback);
  433.                     $images.unbind('.imagesLoaded', imgLoaded);
  434.                 }
  435.             }
  436.         }

  437.         // if no images, trigger immediately
  438.         if (!len) {
  439.             triggerCallback();
  440.         }

  441.         $images.bind('load.imagesLoaded error.imagesLoaded', imgLoaded).each(function() {
  442.             // cached images don't fire load sometimes, so we reset src.
  443.             var src = this.src;
  444.             // webkit hack from http://groups.google.com/group/jquery-dev/browse_thread/thread/eee6ab7b2da50e1f
  445.             // data uri bypasses webkit log warning (thx doug jones)
  446.             this.src = blank;
  447.             this.src = src;
  448.         });

  449.         return $this;
  450.     };

  451.     //修复IE的resize问题(网上找来的)
  452.     $.fn.wresize = function(f) {
  453.         version = '1.1';
  454.         wresize = { fired: false, width: 0 };

  455.         function resizeOnce() {
  456.             if ($.browser.msie) {
  457.                 if (!wresize.fired) {
  458.                     wresize.fired = true;
  459.                 }
  460.                 else {
  461.                     var version = parseInt($.browser.version, 10);
  462.                     wresize.fired = false;
  463.                     if (version < 7) {
  464.                         return false;
  465.                     }
  466.                     else if (version == 7) {
  467.                         //a vertical resize is fired once, an horizontal resize twice
  468.                         var width = $(window).width();
  469.                         if (width != wresize.width) {
  470.                             wresize.width = width;
  471.                             return false;
  472.                         }
  473.                     }
  474.                 }
  475.             }

  476.             return true;
  477.         }

  478.         function handleWResize(e) {
  479.             if (resizeOnce()) {
  480.                 return f.apply(this, [e]);
  481.             }
  482.         }

  483.         this.each(function() {
  484.             if (this == window) {
  485.                 $(this).resize(handleWResize);
  486.             }
  487.             else {
  488.                 $(this).resize(f);
  489.             }
  490.         });

  491.         return this;
  492.     };
  493. })(jQuery);
复制代码

全部评论 0

您需要登录后才可以回帖 立即登录
登录
0
0
0
返回顶部