讲一下大概的原理吧,还是先上图:
功能描述:
- 根据不同菜单的属性值分别加载不同的数据
- 下拉滚动条到一定位置预加载图片,滚动条拉到最底下的时候渲染html;
- 鼠标移到菜单,切换各个图片列表;
- 鼠标移到图片列表上,显示详细信息;
技术实现方案:
先梳理一下从加载到显示的流程:
1. 加载数据
2. 拼接HTML写入到页面
3. 检查刚刚写入的HTML中的img是否全部加载完成,如果是,进入5、否则进入4
4. 等待图片加载完成
5. 计算每个元素的位置
一开始的时候最头疼的是如何定位的问题,后来经过朋友指导终于解决:计算总共有多少列图片并且把每一列的高度都放到一个数组里面。每当一张图片加载完成的时候就查找这个数组里面最小的值,并且定位当前图片的top设置为这个值,完成后把这个图片的高度加上数组里面的最小值并且返回到数组里面,依次类推。
PS:因为这个功能代码太多,只能作基本的简单分解代码了:
// 创建用于记录每列高度的数组
_getLowestCol: function() {
t._cols = new Array(5),min = 0;
// 初始化为0
for (var i = 0; i < t._cols.length; i++) {
if (cols[i] < cols[min]) {
min = i;
}
return min;
}
},
_reposition: function() {
t._grids.each(function(i, grid) {
//先显示出来
grid = $(grid).show();
var height = grid.outerHeight(), min = t._getLowestCol();
// 定位
grid.animate({
left: (t._colWidth + t._colSpacing) * min,
top: t._cols[min],
opacity: 1
},1000);
// 记录高度
t._cols[min] += height;
});
}
其次开发过程中遇到的难题是:因为如上图所示,鼠标移动到菜单栏需要切换图片列表,并且分别需要用瀑布流加载不同类型的数据。所以要处理在切换页面的时候如何才能做到每个页面只执行一次代码请求接口,而不需要每一次切换都重新请求数据接口,仅仅执行切换显示图片列表的操作就可以了。
考虑到每一个菜单都有一个自定义属性,所以这个问题轻易地解决了:建立一个对象来记录当前菜单是否已经执行过代码,如果没有就执行请求数据 。
var isLoad = {};//是否载入过
labelType.mouseover(function() {
var i = $(this).index();
var api = _this.attr('api');//接口标识
if(! isLoad[ api ]){
isLoad[ api ] = i;
loadData(wrapper, api);
}
});
以下为全部代码:
html:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title></title>
<style type="text/css">
*{margin:0;padding:0;}
ul,li{ list-style-type:none;}
li img{width:100%;list-style:none;}
</style>
</head>
<body>
<div class="photo_box">
<ul id="container" style="border:1px solid #000;width:80%;height:600px;overflow:hidden;margin:0 auto;position: relative;">
</ul>
<div id="loading" class="loading" style="text-align: center;margin-top: 20px;font-size: 1.2em;">加载中...</div>
<div id="more" class="more"style="text-align: center;margin-top: 20px;font-size: 1.2em;"><input type="button" value="更 多" id="clear" /></div>
</div>
<script type="text/javascript" src="/UploadFiles/2021-04-02/sea.js">
js:
/**
* 瀑布流布局组件类
* @param {Object} options 组件设置
* @param {NodeList} options.container 瀑布流容器
* @param {String} options.dataURL 数据地址
* @param {String} [options.dataType='jsonp'] 数据类型,json或jsonp
* @param {String} options.template 模板编辑
* @param {Number} [options.colWidth] 图片大小。
* @param {Number} [options.colSpacing] 列间隔。
* @param {Number} [options.rowSpacing] 行间隔。
* @param {Number} [options.page=1] 数据开始页码
* @param {Number} [options.pageEnd] 数据末尾页码
* @pageNum() 函数,如果不需要现在加载也是,需要把函数里面的判断去掉。
从加载到显示的流程
1. 加载数据
2. 拼接HTML写入到页面
3. 检查刚刚写入的HTML中的img是否全部加载完成,如果是,进入5、否则进入4
4. 等待图片加载完成
5. 计算每个元素的位置
*/
define(function(require, exports, module) {
'use strict';
var Tmpl = require('lib/tmpl/2.1.x/index.js'),
$ = require('lib/jquery/1.11.x/index.js');
var waterFall = {
init: function(options) {
var t = this;
t._container = options.container;
t._template = options.template;
t._colWidth = options.colWidth;
t._colSpacing = options.colSpacing;
t._rowSpacing = options.rowSpacing;
t.dataURL = options.dataURL;
t.dataType = options.dataType;
t.page = options.page;
t.pageEnd = options.pageEnd;
t._switch = false;
//计算有几列 总宽度 / (列宽 + 列间隔)
t._totalCols = parseInt(t._container.width() / (t._colWidth + t._colSpacing));
// 创建用于记录每列高度的数组
t._cols = new Array(t._totalCols);
// 初始化为0
for (var i = 0; i < t._cols.length; i++) {
t._cols[i] = 0;
}
t._loadingPage = options.page || 0;
t._loadNext(options);
//下拉滚动条加载
var lastTime = new Date().getTime();
$(window).scroll(function() {
if ( !t._switch ) {
//判断是否滚动过快,在ie下
var thisTime = new Date().getTime();
if (thisTime - lastTime < 50) {
console.log(thisTime - lastTime);
lastTime = thisTime;
return;
}
if ($(window).scrollTop() + $(window).height() >= document.documentElement.scrollHeight) {
lastTime = thisTime;
t._loadNext();
}
}
});
},
//加载器
_loadNext: function(t) {
var t = this;
t._switch = true;
//请求数据
if (!t.trigger) {
$.ajax({
url: t.dataURL,
data: { page: ++t._loadingPage },
dataType:t.dataType,
success: function(response){
t.trigger = t._completeLoading(response);
},
error:function(){console.log('Error! 请求有误');}
});
}
return false;
},
//加载完数据调用此函数
_completeLoading: function(result) {
var t = this;
if (t._loadingPage >= t.pageEnd) {
$('#more').hide();
$('#loading').html('<p>已是最后一页了喔 ^_^ ^_^</p>');
return true;
}
else {
//if (!pageNum()) {
t._add(result);
//};
}
return false;
},
//添加格子
_add: function(result) {
var t = this, grids = '';
//调用模板
var content = Tmpl.render(t._template, {data:result.data});
//原始定位
t._grids = $(content).css({
position: 'absolute',
left: t._container.width(),
top: t._container.height(),
width: t._colWidth,
opacity: 0
});
//把Html添加到容器
t._container.append(t._grids);
// 执行一次_reposition,如果所有图片都加载完成,该方法返回true,否则返回false
if ( !t._reposition() ) {
// 有图片未加载完,监听onload和onerror
t._grids.find('img').bind('load error', function() {
this.loaded = true;
// 有图片加载完成,再次执行_reposition
if (t._grids) {
t._reposition();
}
});
}
},
// 此方法用于获取高度最低的列
_getLowestCol: function() {
var cols = this._cols, min = 0;
for (var i = 1; i < cols.length; i++) {
if (cols[i] < cols[min]) {
min = i;
}
}
return min;
},
//定位
_reposition: function() {
var t = this, allImgsLoaded = true;
// 检测图片是否全部加载完成
t._grids.find('img').each(function(i, img) {
if (!img.loaded && !img.complete) {
allImgsLoaded = false;
}
return allImgsLoaded;
});
if (allImgsLoaded) {
t._grids.each(function(i, grid) {
//先显示出来
grid = $(grid).show();
var height = grid.outerHeight(), min = t._getLowestCol();
// 非第一行的时候,要加上行间隔
if (t._cols[min]) { t._cols[min] += t._rowSpacing; }
// 定位
grid.animate({
left: (t._colWidth + t._colSpacing) * min,
top: t._cols[min],
opacity: 1
},1000);
// 记录高度
t._cols[min] += height;
});
// 重设外层容器高度为最高列高度
t._container.css( 'height', Math.max.apply(Math, t._cols) );
t._switch = false;
delete t._grids;
}
return allImgsLoaded;
},
}
return waterFall;
});
以上就是本文的全部内容,希望对大家学习javascript程序设计有所帮助。
免责声明:本站资源来自互联网收集,仅供用于学习和交流,请遵循相关法律法规,本站一切资源不代表本站立场,如有侵权、后门、不妥请联系本站删除!
稳了!魔兽国服回归的3条重磅消息!官宣时间再确认!
昨天有一位朋友在大神群里分享,自己亚服账号被封号之后居然弹出了国服的封号信息对话框。
这里面让他访问的是一个国服的战网网址,com.cn和后面的zh都非常明白地表明这就是国服战网。
而他在复制这个网址并且进行登录之后,确实是网易的网址,也就是我们熟悉的停服之后国服发布的暴雪游戏产品运营到期开放退款的说明。这是一件比较奇怪的事情,因为以前都没有出现这样的情况,现在突然提示跳转到国服战网的网址,是不是说明了简体中文客户端已经开始进行更新了呢?
更新日志
- 小骆驼-《草原狼2(蓝光CD)》[原抓WAV+CUE]
- 群星《欢迎来到我身边 电影原声专辑》[320K/MP3][105.02MB]
- 群星《欢迎来到我身边 电影原声专辑》[FLAC/分轨][480.9MB]
- 雷婷《梦里蓝天HQⅡ》 2023头版限量编号低速原抓[WAV+CUE][463M]
- 群星《2024好听新歌42》AI调整音效【WAV分轨】
- 王思雨-《思念陪着鸿雁飞》WAV
- 王思雨《喜马拉雅HQ》头版限量编号[WAV+CUE]
- 李健《无时无刻》[WAV+CUE][590M]
- 陈奕迅《酝酿》[WAV分轨][502M]
- 卓依婷《化蝶》2CD[WAV+CUE][1.1G]
- 群星《吉他王(黑胶CD)》[WAV+CUE]
- 齐秦《穿乐(穿越)》[WAV+CUE]
- 发烧珍品《数位CD音响测试-动向效果(九)》【WAV+CUE】
- 邝美云《邝美云精装歌集》[DSF][1.6G]
- 吕方《爱一回伤一回》[WAV+CUE][454M]
