Files
HTCloud/HT.Cloud.Web/wwwroot/lib/layui/modules/flow.js

205 lines
6.5 KiB
JavaScript
Raw Normal View History

2023-03-10 16:39:21 +08:00
/**
2024-11-14 09:01:55 +08:00
* flow 流加载组件
2023-03-10 16:39:21 +08:00
*/
2024-11-14 09:01:55 +08:00
2023-03-10 16:39:21 +08:00
layui.define('jquery', function(exports){
"use strict";
2024-11-14 09:01:55 +08:00
2023-03-10 16:39:21 +08:00
var $ = layui.$, Flow = function(options){}
,ELEM_MORE = 'layui-flow-more'
,ELEM_LOAD = '<i class="layui-anim layui-anim-rotate layui-anim-loop layui-icon ">&#xe63e;</i>';
//主方法
Flow.prototype.load = function(options){
var that = this, page = 0, lock, isOver, lazyimg, timer;
options = options || {};
2024-11-14 09:01:55 +08:00
2023-03-10 16:39:21 +08:00
var elem = $(options.elem); if(!elem[0]) return;
2024-11-14 09:01:55 +08:00
var scrollElem = $(options.scrollElem || document); // 滚动条所在元素
var threshold = 'mb' in options ? options.mb : 50; // 临界距离
var isAuto = 'isAuto' in options ? options.isAuto : true; // 否自动滚动加载
var moreText = options.moreText || "加载更多"; // 手动加载时,加载更多按钮文案
var end = options.end || '没有更多了'; // “末页”显示文案
var direction = options.direction || 'bottom';
var isTop = direction === 'top';
// 重复执行时清理旧的事件绑定
that._cleanup(elem, scrollElem);
2023-03-10 16:39:21 +08:00
//滚动条所在元素是否为document
2024-11-14 09:01:37 +08:00
var notDocument = options.scrollElem && options.scrollElem !== document;
2024-11-14 09:01:55 +08:00
2023-03-10 16:39:21 +08:00
//加载更多
2024-11-14 09:01:55 +08:00
var ELEM_TEXT = '<cite>' + moreText + '</cite>'
2023-03-10 16:39:21 +08:00
,more = $('<div class="layui-flow-more"><a href="javascript:;">'+ ELEM_TEXT +'</a></div>');
2024-11-14 09:01:55 +08:00
2023-03-10 16:39:21 +08:00
if(!elem.find('.layui-flow-more')[0]){
2024-11-14 09:01:55 +08:00
elem[isTop ? 'prepend' : 'append'](more);
2023-03-10 16:39:21 +08:00
}
2024-11-14 09:01:55 +08:00
2023-03-10 16:39:21 +08:00
//加载下一个元素
2024-11-14 09:01:55 +08:00
var next = function(html, over){
var scrollHeightStart = notDocument ? scrollElem.prop('scrollHeight') : document.documentElement.scrollHeight;
var scrollTopStart = scrollElem.scrollTop();
2023-03-10 16:39:21 +08:00
html = $(html);
2024-11-14 09:01:55 +08:00
more[isTop ? 'after' : 'before'](html);
2023-03-10 16:39:21 +08:00
over = over == 0 ? true : null;
over ? more.html(end) : more.find('a').html(ELEM_TEXT);
isOver = over;
lock = null;
lazyimg && lazyimg();
2024-11-14 09:01:55 +08:00
if(isTop){
var scrollHeightEnd = notDocument ? scrollElem.prop('scrollHeight') : document.documentElement.scrollHeight;
if(page === 1){
// 首次渲染后滑动到底部
scrollElem.scrollTop(scrollHeightEnd);
}else if(page > 1){
var nextElementHeight = scrollHeightEnd - scrollHeightStart;
scrollElem.scrollTop(scrollTopStart + nextElementHeight);
}
}
2023-03-10 16:39:21 +08:00
};
2024-11-14 09:01:55 +08:00
2023-03-10 16:39:21 +08:00
//触发请求
var done = function(){
lock = true;
more.find('a').html(ELEM_LOAD);
typeof options.done === 'function' && options.done(++page, next);
};
2024-11-14 09:01:55 +08:00
2023-03-10 16:39:21 +08:00
done();
2024-11-14 09:01:55 +08:00
2023-03-10 16:39:21 +08:00
//不自动滚动加载
2024-11-14 09:01:55 +08:00
more.find('a').on('click.flow', function(){
2023-03-10 16:39:21 +08:00
var othis = $(this);
if(isOver) return;
lock || done();
});
2024-11-14 09:01:55 +08:00
2023-03-10 16:39:21 +08:00
//如果允许图片懒加载
if(options.isLazyimg){
2024-11-14 09:01:55 +08:00
lazyimg = that.lazyimg({
2023-03-10 16:39:21 +08:00
elem: options.elem + ' img'
,scrollElem: options.scrollElem
2024-11-14 09:01:55 +08:00
,direction: options.direction
2023-03-10 16:39:21 +08:00
});
}
2024-11-14 09:01:55 +08:00
2023-03-10 16:39:21 +08:00
if(!isAuto) return that;
2024-11-14 09:01:55 +08:00
scrollElem.on('scroll.flow', function(){
2023-03-10 16:39:21 +08:00
var othis = $(this), top = othis.scrollTop();
2024-11-14 09:01:55 +08:00
2023-03-10 16:39:21 +08:00
if(timer) clearTimeout(timer);
if(isOver || !elem.width()) return; //如果已经结束,或者元素处于隐藏状态,则不执行滚动加载
2024-11-14 09:01:55 +08:00
2023-03-10 16:39:21 +08:00
timer = setTimeout(function(){
//计算滚动所在容器的可视高度
2024-11-14 09:01:37 +08:00
var height = notDocument ? othis.height() : $(window).height();
2024-11-14 09:01:55 +08:00
2023-03-10 16:39:21 +08:00
//计算滚动所在容器的实际高度
2024-11-14 09:01:37 +08:00
var scrollHeight = notDocument
2023-03-10 16:39:21 +08:00
? othis.prop('scrollHeight')
: document.documentElement.scrollHeight;
//临界点
2024-11-14 09:01:55 +08:00
if(!isTop ? scrollHeight - top - height <= threshold : top <= threshold){
2023-03-10 16:39:21 +08:00
lock || done();
}
}, 100);
});
2024-11-14 09:01:55 +08:00
2023-03-10 16:39:21 +08:00
return that;
};
2024-11-14 09:01:55 +08:00
2023-03-10 16:39:21 +08:00
//图片懒加载
Flow.prototype.lazyimg = function(options){
var that = this, index = 0, haveScroll;
options = options || {};
2024-11-14 09:01:55 +08:00
2023-03-10 16:39:21 +08:00
var scrollElem = $(options.scrollElem || document); //滚动条所在元素
var elem = options.elem || 'img';
2024-11-14 09:01:55 +08:00
var direction = options.direction || 'bottom';
var isTop = direction === 'top';
2023-03-10 16:39:21 +08:00
//滚动条所在元素是否为document
2024-11-14 09:01:37 +08:00
var notDocument = options.scrollElem && options.scrollElem !== document;
2024-11-14 09:01:55 +08:00
2023-03-10 16:39:21 +08:00
//显示图片
var show = function(item, height){
var start = scrollElem.scrollTop(), end = start + height;
2024-11-14 09:01:37 +08:00
var elemTop = notDocument ? function(){
2023-03-10 16:39:21 +08:00
return item.offset().top - scrollElem.offset().top + start;
}() : item.offset().top;
/* 始终只加载在当前屏范围内的图片 */
2024-11-14 09:01:55 +08:00
if((isTop ? elemTop + item.height() : elemTop) >= start && elemTop <= end){
2023-03-10 16:39:21 +08:00
if(item.attr('lay-src')){
var src = item.attr('lay-src');
layui.img(src, function(){
var next = that.lazyimg.elem.eq(index);
item.attr('src', src).removeAttr('lay-src');
2024-11-14 09:01:55 +08:00
2023-03-10 16:39:21 +08:00
/* 当前图片加载就绪后,检测下一个图片是否在当前屏 */
next[0] && render(next);
index++;
}, function(){
var next = that.lazyimg.elem.eq(index);
item.removeAttr('lay-src');
});
}
}
}, render = function(othis, scroll){
2024-11-14 09:01:55 +08:00
2023-03-10 16:39:21 +08:00
//计算滚动所在容器的可视高度
2024-11-14 09:01:37 +08:00
var height = notDocument ? (scroll||scrollElem).height() : $(window).height();
2023-03-10 16:39:21 +08:00
var start = scrollElem.scrollTop(), end = start + height;
that.lazyimg.elem = $(elem);
if(othis){
show(othis, height);
} else {
//计算未加载过的图片
for(var i = 0; i < that.lazyimg.elem.length; i++){
2024-11-14 09:01:37 +08:00
var item = that.lazyimg.elem.eq(i), elemTop = notDocument ? function(){
2023-03-10 16:39:21 +08:00
return item.offset().top - scrollElem.offset().top + start;
}() : item.offset().top;
2024-11-14 09:01:55 +08:00
2023-03-10 16:39:21 +08:00
show(item, height);
index = i;
2024-11-14 09:01:55 +08:00
2023-03-10 16:39:21 +08:00
//如果图片的top坐标超出了当前屏则终止后续图片的遍历
if(elemTop > end) break;
}
}
};
2024-11-14 09:01:55 +08:00
2023-03-10 16:39:21 +08:00
render();
2024-11-14 09:01:55 +08:00
2023-03-10 16:39:21 +08:00
if(!haveScroll){
var timer;
2024-11-14 09:01:55 +08:00
scrollElem.on('scroll.lazyimg' , function(){
2023-03-10 16:39:21 +08:00
var othis = $(this);
if(timer) clearTimeout(timer)
timer = setTimeout(function(){
render(null, othis);
}, 50);
2024-11-14 09:01:55 +08:00
});
2023-03-10 16:39:21 +08:00
haveScroll = true;
}
return render;
};
2024-11-14 09:01:55 +08:00
// 重复执行时清理旧的事件绑定,私有方法
Flow.prototype._cleanup = function(elem, scrollElem){
scrollElem.off('scroll.flow').off('scroll.lazyimg');
elem.find('.layui-flow-more').find('a').off('click.flow');
elem.html('');
}
2023-03-10 16:39:21 +08:00
//暴露接口
exports('flow', new Flow());
});