博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
重构项目之二:使用瀑布流效果加载图片
阅读量:6266 次
发布时间:2019-06-22

本文共 7944 字,大约阅读时间需要 26 分钟。

虽然这个功能最后使用了另外的插件,但是还是讲一下大概的原理吧,还是先上图:

 

 

功能描述:

  1. 根据不同菜单的属性值分别加载不同的数据

  2. 下拉滚动条到一定位置预加载图片,滚动条拉到最底下的时候渲染html;

  3. 鼠标移到菜单,切换各个图片列表;

  4. 鼠标移到图片列表上,显示详细信息;

 

技术实现方案:

  先梳理一下从加载到显示的流程:

  1. 加载数据

  2. 拼接HTML写入到页面
  3. 检查刚刚写入的HTML中的img是否全部加载完成,如果是,进入5、否则进入4
  4. 等待图片加载完成
  5. 计算每个元素的位置

 

 

一开始的时候最头疼的是如何定位的问题,后来经过朋友指导终于解决:

  计算总共有多少列图片并且把每一列的高度都放到一个数组里面。每当一张图片加载完成的时候就查找这个数组里面最小的值,并且定位当前图片的top设置为这个值,完成后把这个图片的高度加上数组里面的最小值并且返回到数组里面,依次类推。 

 

PS:因为这个功能代码太多,只能作基本的简单分解代码了: 

1 // 创建用于记录每列高度的数组 2 _getLowestCol: function() { 3     t._cols = new Array(5),min = 0; 4     // 初始化为0 5     for (var i = 0; i < t._cols.length; i++) { 6         if (cols[i] < cols[min]) { 7             min = i; 8         } 9         return min;10     }11 },12 _reposition: function() {13     t._grids.each(function(i, grid) {14         //先显示出来15         grid = $(grid).show();16         17         var height = grid.outerHeight(), min = t._getLowestCol();18 19         // 定位20         grid.animate({21             left: (t._colWidth + t._colSpacing) * min,22             top: t._cols[min],23             opacity: 124         },1000);25         // 记录高度26         t._cols[min] += height;27     });28 29 }
View Code

 

 

其次开发过程中遇到的难题是:

  因为如上图所示,鼠标移动到菜单栏需要切换图片列表,并且分别需要用瀑布流加载不同类型的数据。所以要处理在切换页面的时候如何才能做到每个页面只执行一次代码请求接口,而不需要每一次切换都重新请求数据接口,仅仅执行切换显示图片列表的操作就可以了。

  考虑到每一个菜单都有一个自定义属性,所以这个问题轻易地解决了:建立一个对象来记录当前菜单是否已经执行过代码,如果没有就执行请求数据 。 

1 var isLoad = {};//是否载入过 2 labelType.mouseover(function() { 3     var i = $(this).index(); 4     var api = _this.attr('api');//接口标识 5      6     if(! isLoad[ api ]){ 7         isLoad[ api ] = i; 8         loadData(wrapper, api); 9     }10     11 });
View Code

 

 

以下为全部代码:

html:

1  2  3  4 
5 6 11 12 13
14
    15
16
加载中...
17
18
19 20 21 55
View Code

 

 

js:

1 /**  2  * 瀑布流布局组件类  3  * @param {Object} options 组件设置  4  *        @param {NodeList} options.container 瀑布流容器  5  *        @param {String} options.dataURL 数据地址  6  *        @param {String} [options.dataType='jsonp'] 数据类型,json或jsonp  7  *        @param {String}    options.template 模板编辑  8  *        @param {Number} [options.colWidth] 图片大小。  9  *        @param {Number} [options.colSpacing] 列间隔。 10  *        @param {Number} [options.rowSpacing] 行间隔。 11  *        @param {Number} [options.page=1] 数据开始页码 12  *        @param {Number} [options.pageEnd] 数据末尾页码 13  14  * @pageNum() 函数,如果不需要现在加载也是,需要把函数里面的判断去掉。 15  16  17  从加载到显示的流程 18  19 1. 加载数据 20 2. 拼接HTML写入到页面 21 3. 检查刚刚写入的HTML中的img是否全部加载完成,如果是,进入5、否则进入4 22 4. 等待图片加载完成 23 5. 计算每个元素的位置 24  25  */ 26  27  28 var waterFall = { 29     init: function(options) { 30         var t = this; 31         t._container = options.container; 32         t._colWidth = options.colWidth; 33         t._colSpacing = options.colSpacing; 34         t._rowSpacing = options.rowSpacing; 35         t.dataURL = options.dataURL; 36         t.dataType = options.dataType; 37         t.page = options.page; 38         t.pageEnd = options.pageEnd; 39         t._switch = false; 40  41         //计算有几列 总宽度 / (列宽 + 列间隔) 42         t._totalCols = parseInt(t._container.width() / (t._colWidth + t._colSpacing)); 43  44         // 创建用于记录每列高度的数组 45         t._cols = new Array(t._totalCols); 46         // 初始化为0 47         for (var i = 0; i < t._cols.length; i++) { 48             t._cols[i] = 0; 49         } 50  51         t._loadingPage = options.page || 0; 52         t._loadNext(options); 53  54         //下拉滚动条加载 55         var lastTime = new Date().getTime(); 56  57         $(window).scroll(function() { 58  59             if ( !t._switch ) { 60                 //判断是否滚动过快,在ie下 61                 var thisTime = new Date().getTime(); 62  63                 if (thisTime - lastTime < 50) { 64                     console.log(thisTime - lastTime); 65                     lastTime = thisTime; 66                     return; 67                 } 68  69                 if ($(window).scrollTop() + $(window).height() >= document.documentElement.scrollHeight) { 70                     lastTime = thisTime; 71                     t._loadNext(); 72                 } 73             } 74         }); 75     }, 76     //加载器 77     _loadNext: function(t) { 78         var t = this; 79  80         t._switch = true; 81         //请求数据 82         if (!t.trigger) { 83             $.ajax({ 84                 url: t.dataURL, 85                 data: { page: ++t._loadingPage }, 86                 dataType:t.dataType, 87                 success: function(response){ 88                      89                     t.trigger = t._completeLoading(response); 90  91                 }, 92                 error:function(){console.log('Error! 请求有误');} 93             });     94         } 95         return false; 96     }, 97     //加载完数据调用此函数 98     _completeLoading: function(result) { 99         var t = this;100         if (t._loadingPage >= t.pageEnd) {101             $('#more').hide();102             $('#loading').html('

已是最后一页了喔 ^_^ ^_^

');103 return true;104 }105 else {106 //if (!pageNum()) {
107 t._add(result);108 //};109 }110 111 return false;112 },113 //添加格子114 _add: function(result) {115 var t = this, grids = '';116 var content = '';117 for(var i = 0; i < 10; i++) {118 content += '
  • ' +119 '' +120 '
  • ';121 }122 123 console.log(content);124 //原始定位125 t._grids = $(content).css({126 position: 'absolute',127 left: t._container.width(),128 top: t._container.height(), 129 width: t._colWidth,130 opacity: 0131 });132 133 //把Html添加到容器134 t._container.append(t._grids);135 136 // 执行一次_reposition,如果所有图片都加载完成,该方法返回true,否则返回false137 if ( !t._reposition() ) {138 // 有图片未加载完,监听onload和onerror139 t._grids.find('img').bind('load error', function() {140 this.loaded = true;141 // 有图片加载完成,再次执行_reposition142 if (t._grids) {143 t._reposition();144 }145 });146 }147 },148 // 此方法用于获取高度最低的列149 _getLowestCol: function() {150 var cols = this._cols, min = 0;151 for (var i = 1; i < cols.length; i++) {152 if (cols[i] < cols[min]) {153 min = i;154 }155 }156 return min;157 },158 //定位159 _reposition: function() {160 161 var t = this, allImgsLoaded = true;162 163 // 检测图片是否全部加载完成164 t._grids.find('img').each(function(i, img) {165 if (!img.loaded && !img.complete) {166 167 allImgsLoaded = false;168 }169 return allImgsLoaded;170 });171 172 if (allImgsLoaded) {173 t._grids.each(function(i, grid) {174 //先显示出来175 grid = $(grid).show();176 177 var height = grid.outerHeight(), min = t._getLowestCol();178 179 // 非第一行的时候,要加上行间隔180 if (t._cols[min]) { t._cols[min] += t._rowSpacing; }181 // 定位182 grid.animate({183 left: (t._colWidth + t._colSpacing) * min,184 top: t._cols[min],185 opacity: 1186 },1000);187 // 记录高度188 t._cols[min] += height;189 });190 // 重设外层容器高度为最高列高度191 t._container.css( 'height', Math.max.apply(Math, t._cols) );192 t._switch = false;193 delete t._grids;194 }195 196 return allImgsLoaded;197 },198 }
    View Code

     

     

     

     

    PS:欢迎来我秀欣赏美女直播喔(*^__^*) :

     

    转载于:https://www.cnblogs.com/Travel/p/4463820.html

    你可能感兴趣的文章
    ubuntu常用命令精选
    查看>>
    UML类图
    查看>>
    企业上市上市央企大面积亏损折射出啥弊端?
    查看>>
    DXP_protel2004_原理图设计基础_集成运放原理图设计学习
    查看>>
    powershell--uninstall webapplication
    查看>>
    ubuntu配置vsftpd记录
    查看>>
    日期控件Android 自定义日历控件
    查看>>
    Java多线程编程:变量共享分析(Thread)
    查看>>
    word如何自动生成目录
    查看>>
    疯狂暑期学习计划~~~
    查看>>
    Mysql查询大表出现的一个错误
    查看>>
    Scala 中的foreach和map方法比较
    查看>>
    使用OWIN作为WebAPI的宿主
    查看>>
    阿里巴巴、腾讯、百度的面试问题笔知识汇总(两)
    查看>>
    如果他们在未来的几年内技术水平没有突破性的提升,或者缺乏一点灵性和品味,那么可能在未来很长一段时间内,他们都会保持这个薪资水平(转)...
    查看>>
    修改setup.py的源
    查看>>
    SQL Server 常用高级语法笔记
    查看>>
    IOS开发之SVN的使用
    查看>>
    百度.搜狐...2015产品经理面试题
    查看>>
    Rewriting History with Git Rebase
    查看>>