zoukankan      html  css  js  c++  java
  • 瀑布流网页的实现中遇到的问题和解决方法

    CUED-迅雷用户体验设计中心

     

    <:section class="main" jQuery11020835607558477726="9">

    浅谈个人在瀑布流网页的实现中遇到的问题和解决方法

    先上Demo

    瀑布流排序 : http://cued.xunlei.com/demos/publ/demo1.php

    瀑布流+无限拖  http://cued.xunlei.com/demos/publ/demo2.html

    瀑布流+无限拖 (js获取图片高度版)  http://cued.xunlei.com/demos/publ/demo3.html

    补充说明:因为之前的图片命名规则过于简单,容易被盗链啥的,被管理员发现。所以用php的Mcrypt函数库加密了一下图片名称。json.php获取图片的算法也做了一些修改 (当然为了保证已经远程调用我们图片的站点能够正常打开,原图是保留的,老客户请放心使用~另外加密算法很简单,DES+凯撒2层,有兴趣的同学可以破解一下,密钥提示:每天的图片名称都不同哦~)

    为了方便大家本地调试程序,现将过去版本打包,下载地址:

    迅雷方舟下载猛击这里

    迅雷快传下载狂按这里

    随着pinterest的走红,瀑布流式的布局被越来越多的网站所使用,这种布局确实有很多好处,图片列表页有很强大的视觉感染力,而且还提高了用户“发现好图”的效率。瀑布流的实现有很多种方式,之前淘宝UED有篇文章详细的介绍过各种方式的优劣。今天我们主要讨论一下绝对排序来实现瀑布流的方式 即 Pinterest 采用的方式。

    首先说下瀑布流的排序算法,参考demo1,思路非常简单,我们把瀑布流拆成三个部分来看:容器、列、格子

    1.先计算当前屏幕最多能容纳几列瀑布,其值为 "向下取整(屏幕可见区域宽度/(格子宽度+间距))";

    2.为了保证容器的居中,将容器的宽度设置为 列数* (格子宽度+间距) – 间距,这里需要注意的是 当容器的宽度计算出来之后再显示,否则会造成页面宽度的抖动,影响体验。;

    3.排序开始,先把前N(N为列数)个格子分别放到每一列中,然后每次寻找高度最小的一列,把格子放进去(left值为列序号*(格子宽度+间距),top值为 列高+间距),并刷新列的高度,遍历所有格子直到所有的格子都被排序。
     

    最后将事件句柄绑定到window.onload和window.onresize上,一个瀑布流布局的页面就出来了。

    这样的排序算法看起来很美好,可真正结合异步加载数据应用到页面里还要解决以下几个问题

    1.当缩放浏览器窗口时会不断地触发事件,如果每次都响应的话会狂耗性能,需要在缩放动作结束后再执行重排方法。

    2.页面滚动到底部请求数据成功之后只对新增的节点重排。

    3.如果服务器无法给出图片高度,需要在图片加载完毕之后再进行重排。

    第一个问题我是用setTimeout和clearTimeout来解决的,思路是窗口变化之后开始计时,如果窗口还在变换则从新开始计时,窗口不再变化则延时(很短的时间)触发重排事件。暂时只想到这个,这里应该还有更好的方法。
    代码如下

    var re;
    window.onresize = function() {
        clearTimeout(re);
        re = setTimeout(resize,100);
    };

    第二个问题在于如果每次有新的数据加载,都要对整个容器内的节点进行重排,非常消耗性能。解决思路:

    1.将列保存在全局数组中,每次重排或者新增格子之后更新数组的数据,这样下次执行排序算法的时候可以直接调用。
    2.将新增格子保存在数组中作为参数传递给排序算法,仅对新格子进行遍历和操作。

    第三个问题是如果服务器无法给出图片尺寸,那么必须在图片完全加载完毕之后才可进行排序(因为高度是实时获取的,图片不全高度有误差),这里没有什么好办法,只能遍历图片,每张图片加载成功后执行一个回调函数,将加载成功的图片数量+1,当加载成功的图片数量等于图片总数的时候执行排序方法。缺点是有一张图片加载不成功就无法看到所有的,真正项目中还是需要在异步加载数据的时候获取图片尺寸。

    好了,以上就是在这次瀑布流实现过程中遇到的问题和解决方法,由一开始加载3-4屏就卡死到现在可以无限加载(ff,chrome),深感优化js的必要性和无限性。一点小心得写在这里权当抛砖引玉,大家对瀑布流实现的优化有什么见解欢迎一起交流讨论。

    PS:一点视觉上的优化,如果服务器可以给出图片尺寸的话,返回的json字符串应该是按照高度从高到低排序的,这样可以使瀑布流底部尽量持平(感谢书生的指点)。

    PS2:感谢 xiaoqiang 的分享,demo3中使用了通过文件头信息获取尺寸的方法,格子在图片加载完毕之前就可以完成排序,但是那个方法在ie下获取的头信息有些误差,不知道问题出在哪里?望高手指点

    PS3:抛砖引玉的目的达到了,这么多人一起思考和讨论,让这个瀑布流越来越快啦~潜水的高手们该出手了

    应观众要求贴出php代码,其中用了2种方式试图获取图片高度,均不准确

    <?php
    $num = $_POST["num"]; //获取加载数量
    $t = "{images :["; //构建json字符串
    for($i=0;$i<($num-1);$i++)
    {
      $src=rand(1,84);
      $src=(string)$src;
      if(strlen($src)  == 1) {$src = "00" . $src;}
      else if(strlen($src) == 2) {$src = "0" . $src;} //处理随机字符串
      $img = imagecreatefromjpeg("img/P_".$src.".jpg");//PHP生成图片
      $arr = imagesy($img);//获取图片高度(失败)
      $t = $t."{src : $src,height:$arr},";
    }
      $src=rand(1,84);
      $src=(string)$src;
      if(strlen($src)  == 1) {$src = "00" . $src;}
      else if(strlen($src) == 2) {$src = "0" . $src;}
      $arr = getimagesize("img/P_".$src.".jpg"); //php获取图片信息(失败)
      $t=$t."{src : $src,height:$arr[1]}]}";
      echo $t;
    ?>

    另外截图贴出那个用头信息获取高度的代码在IE下的奇怪效果,chrome的正常尺寸:

    IE8下

    望高手指点……

  • 相关阅读:
    ZOJ 3765 Lights (zju March I)伸展树Splay
    UVA 11922 伸展树Splay 第一题
    UVALive 4794 Sharing Chocolate DP
    ZOJ 3757 Alice and Bod 模拟
    UVALive 3983 捡垃圾的机器人 DP
    UVA 10891 SUM游戏 DP
    poj 1328 Radar Installatio【贪心】
    poj 3264 Balanced Lineup【RMQ-ST查询区间最大最小值之差 +模板应用】
    【转】RMQ-ST算法详解
    poj 3083 Children of the Candy Corn 【条件约束dfs搜索 + bfs搜索】【复习搜索题目一定要看这道题目】
  • 原文地址:https://www.cnblogs.com/firstdream/p/5542387.html
Copyright © 2011-2022 走看看