mirror of
https://github.com/layui/layui.git
synced 2026-02-09 02:09:18 +08:00
* wip(i18n): laydate 国际化 * wip(i18n): colorpicker 国际化 * wip(i18n): laypage 国际化 * fix * update code * wip(i18n): 修改国际化消息对象结构 * wip(i18n): update * wip(i18n): code 国际化 * wip(i18n): dropdown 国际化 * wip(i18n): flow 国际化 * wip(i18n): form 国际化 * wip(i18n): layer 国际化 * wip(i18n): table 国际化 * wip(i18n): transfer 国际化 * wip(i18n): tree 国际化 * wip(i18n): treeTable 控制台提示统一为英文 * wip(i18n): upload 国际化 * wip(i18n): util 国际化 * wip(i18n): update code * wip(i18n): update code * wip(i18n): fix * wip(i18n): 优化 $t 代码细节 * wip(i18n): 修复 laydate lang * wip(i18n): 改进 upload i18n key * wip(i18n): 修复打包后 laydate 和 layer 异常 * wip(i18n): 移除国际化消息中的 `lay` 命名空间 * refactor(i18n): 改进国际化支持 * wip(i18n): 修复 table text.none 切换 locale 无效问题 * style(laydate): 优化逗号格式 * chore(laydate): 优化部分提示 * chore(i18n): 优化演示中部分国际化消息 * refactor: 剔除 laydate 单独版的判断逻辑 为接下来全面支持国际化做铺垫 * wip(i18n): 为 laydate 重新添加完整国际化的支持 * i18n(laydate): 优化 lang() 方法中的逻辑 * chore(util): 删除未使用的代码 * chore(i18n): 优化注释 * docs(i18n): 新增国际化文档(beta) note: 由于时间关系,本次提交仅为初版,该文档尚未完成 * wip(docs): 完善 i18n 文档 * fix(i18n): 修复 laypage 变量定义前使用 * wip(i18n): 转义翻译结果 * fix(i18n): 修复 table 排序 key 无效 * wip(i18n): 优化获取对象中指定路径值的性能 * wip(i18n): 删除 $t 可变长参数重载 * chore(i18n): 删除不必要的注释 * refactor(i18n): laydate 国际化方案迁移至 i18n.$t (#2745) * wip(i18n): 改进 laydate i18nMsg key * update code * wip(i18n): 改进 laydate 面板中的日期格式处理 * wip(i18n): 改进 util.toDateString meridiem 遵循 CLDR day periods 标准 * update code * wip(docs): 优化 i18n 文档示例 * docs(i18n): 优化正式文档 * docs(i18n): 优化部分文案 * docs(i18n): 优化示例 --------- Co-authored-by: 贤心 <3277200+sentsim@users.noreply.github.com>
206 lines
6.5 KiB
JavaScript
206 lines
6.5 KiB
JavaScript
/**
|
||
* flow 流加载组件
|
||
*/
|
||
|
||
|
||
layui.define(['i18n', 'jquery'], function(exports) {
|
||
"use strict";
|
||
|
||
var $ = layui.$;
|
||
var i18n = layui.i18n;
|
||
var Flow = function(options) {};
|
||
var ELEM_MORE = 'layui-flow-more';
|
||
var ELEM_LOAD = '<i class="layui-anim layui-anim-rotate layui-anim-loop layui-icon "></i>';
|
||
|
||
// 主方法
|
||
Flow.prototype.load = function(options) {
|
||
var that = this, page = 0, lock, isOver, lazyimg, timer;
|
||
options = options || {};
|
||
|
||
var elem = $(options.elem); if(!elem[0]) return;
|
||
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 || i18n.$t('flow.loadMore'); // 手动加载时,加载更多按钮文案
|
||
var end = options.end || i18n.$t('flow.noMore'); // “末页”显示文案
|
||
var direction = options.direction || 'bottom';
|
||
var isTop = direction === 'top';
|
||
|
||
// 重复执行时清理旧的事件绑定
|
||
that._cleanup(elem, scrollElem);
|
||
|
||
//滚动条所在元素是否为document
|
||
var notDocument = options.scrollElem && options.scrollElem !== document;
|
||
|
||
//加载更多
|
||
var ELEM_TEXT = '<cite>' + moreText + '</cite>'
|
||
,more = $('<div class="layui-flow-more"><a href="javascript:;">'+ ELEM_TEXT +'</a></div>');
|
||
|
||
if(!elem.find('.layui-flow-more')[0]){
|
||
elem[isTop ? 'prepend' : 'append'](more);
|
||
}
|
||
|
||
//加载下一个元素
|
||
var next = function(html, over){
|
||
var scrollHeightStart = notDocument ? scrollElem.prop('scrollHeight') : document.documentElement.scrollHeight;
|
||
var scrollTopStart = scrollElem.scrollTop();
|
||
html = $(html);
|
||
more[isTop ? 'after' : 'before'](html);
|
||
over = over == 0 ? true : null;
|
||
over ? more.html(end) : more.find('a').html(ELEM_TEXT);
|
||
isOver = over;
|
||
lock = null;
|
||
lazyimg && lazyimg();
|
||
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);
|
||
}
|
||
}
|
||
};
|
||
|
||
//触发请求
|
||
var done = function(){
|
||
lock = true;
|
||
more.find('a').html(ELEM_LOAD);
|
||
typeof options.done === 'function' && options.done(++page, next);
|
||
};
|
||
|
||
done();
|
||
|
||
//不自动滚动加载
|
||
more.find('a').on('click.flow', function(){
|
||
var othis = $(this);
|
||
if(isOver) return;
|
||
lock || done();
|
||
});
|
||
|
||
//如果允许图片懒加载
|
||
if(options.isLazyimg){
|
||
lazyimg = that.lazyimg({
|
||
elem: options.elem + ' img'
|
||
,scrollElem: options.scrollElem
|
||
,direction: options.direction
|
||
});
|
||
}
|
||
|
||
if(!isAuto) return that;
|
||
|
||
scrollElem.on('scroll.flow', function(){
|
||
var othis = $(this), top = othis.scrollTop();
|
||
|
||
if(timer) clearTimeout(timer);
|
||
if(isOver || !elem.width()) return; //如果已经结束,或者元素处于隐藏状态,则不执行滚动加载
|
||
|
||
timer = setTimeout(function(){
|
||
//计算滚动所在容器的可视高度
|
||
var height = notDocument ? othis.height() : $(window).height();
|
||
|
||
//计算滚动所在容器的实际高度
|
||
var scrollHeight = notDocument
|
||
? othis.prop('scrollHeight')
|
||
: document.documentElement.scrollHeight;
|
||
|
||
//临界点
|
||
if(!isTop ? scrollHeight - top - height <= threshold : top <= threshold){
|
||
lock || done();
|
||
}
|
||
}, 100);
|
||
});
|
||
|
||
return that;
|
||
};
|
||
|
||
//图片懒加载
|
||
Flow.prototype.lazyimg = function(options){
|
||
var that = this, index = 0, haveScroll;
|
||
options = options || {};
|
||
|
||
var scrollElem = $(options.scrollElem || document); //滚动条所在元素
|
||
var elem = options.elem || 'img';
|
||
var direction = options.direction || 'bottom';
|
||
var isTop = direction === 'top';
|
||
|
||
//滚动条所在元素是否为document
|
||
var notDocument = options.scrollElem && options.scrollElem !== document;
|
||
|
||
//显示图片
|
||
var show = function(item, height){
|
||
var start = scrollElem.scrollTop(), end = start + height;
|
||
var elemTop = notDocument ? function(){
|
||
return item.offset().top - scrollElem.offset().top + start;
|
||
}() : item.offset().top;
|
||
|
||
/* 始终只加载在当前屏范围内的图片 */
|
||
if((isTop ? elemTop + item.height() : elemTop) >= start && elemTop <= end){
|
||
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');
|
||
|
||
/* 当前图片加载就绪后,检测下一个图片是否在当前屏 */
|
||
next[0] && render(next);
|
||
index++;
|
||
}, function(){
|
||
var next = that.lazyimg.elem.eq(index);
|
||
item.removeAttr('lay-src');
|
||
});
|
||
}
|
||
}
|
||
}, render = function(othis, scroll){
|
||
|
||
//计算滚动所在容器的可视高度
|
||
var height = notDocument ? (scroll||scrollElem).height() : $(window).height();
|
||
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++){
|
||
var item = that.lazyimg.elem.eq(i), elemTop = notDocument ? function(){
|
||
return item.offset().top - scrollElem.offset().top + start;
|
||
}() : item.offset().top;
|
||
|
||
show(item, height);
|
||
index = i;
|
||
|
||
//如果图片的top坐标,超出了当前屏,则终止后续图片的遍历
|
||
if(elemTop > end) break;
|
||
}
|
||
}
|
||
};
|
||
|
||
render();
|
||
|
||
if(!haveScroll){
|
||
var timer;
|
||
scrollElem.on('scroll.lazyimg' , function(){
|
||
var othis = $(this);
|
||
if(timer) clearTimeout(timer)
|
||
timer = setTimeout(function(){
|
||
render(null, othis);
|
||
}, 50);
|
||
});
|
||
haveScroll = true;
|
||
}
|
||
return render;
|
||
};
|
||
|
||
// 重复执行时清理旧的事件绑定,私有方法
|
||
Flow.prototype._cleanup = function(elem, scrollElem){
|
||
scrollElem.off('scroll.flow').off('scroll.lazyimg');
|
||
elem.find('.layui-flow-more').find('a').off('click.flow');
|
||
}
|
||
|
||
//暴露接口
|
||
exports('flow', new Flow());
|
||
});
|