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

427 lines
12 KiB
JavaScript
Raw Normal View History

2023-03-10 16:39:21 +08:00
2024-11-14 09:01:37 +08:00
/** lay 基础模块 | MIT Licensed */
2023-03-10 16:39:21 +08:00
2024-11-14 09:01:37 +08:00
;!function(window){ // gulp build: lay-header
2023-03-10 16:39:21 +08:00
"use strict";
2024-11-14 09:01:37 +08:00
var MOD_NAME = 'lay'; // 模块名
var document = window.document;
2023-03-10 16:39:21 +08:00
2024-11-14 09:01:37 +08:00
// 元素查找
var lay = function(selector){
return new Class(selector);
};
2023-03-10 16:39:21 +08:00
2024-11-14 09:01:37 +08:00
// 构造器
var Class = function(selector){
var that = this;
var elem = typeof selector === 'object' ? function(){
// 仅适配简单元素对象
return layui.isArray(selector) ? selector : [selector];
}() : (
this.selector = selector,
document.querySelectorAll(selector || null)
2023-03-10 16:39:21 +08:00
);
2024-11-14 09:01:37 +08:00
lay.each(elem, function(index, item){
that.push(elem[index]);
});
2023-03-10 16:39:21 +08:00
};
/*
lay 对象操作
*/
2024-11-14 09:01:37 +08:00
Class.fn = Class.prototype = [];
Class.fn.constructor = Class;
2023-03-10 16:39:21 +08:00
2024-11-14 09:01:37 +08:00
// 普通对象深度扩展
2023-03-10 16:39:21 +08:00
lay.extend = function(){
2024-11-14 09:01:37 +08:00
var ai = 1;
var length;
var args = arguments;
var clone = function(target, obj){
target = target || (layui.type(obj) === 'array' ? [] : {}); // 目标对象
2023-03-10 16:39:21 +08:00
for(var i in obj){
2024-11-14 09:01:37 +08:00
// 若值为普通对象,则进入递归,继续深度合并
2023-03-10 16:39:21 +08:00
target[i] = (obj[i] && obj[i].constructor === Object)
? clone(target[i], obj[i])
: obj[i];
}
return target;
2024-11-14 09:01:37 +08:00
};
2023-03-10 16:39:21 +08:00
args[0] = typeof args[0] === 'object' ? args[0] : {};
length = args.length
for(; ai < length; ai++){
if(typeof args[ai] === 'object'){
clone(args[0], args[ai]);
}
}
return args[0];
};
2024-11-14 09:01:37 +08:00
// ie 版本
2023-03-10 16:39:21 +08:00
lay.ie = function(){
var agent = navigator.userAgent.toLowerCase();
return (!!window.ActiveXObject || "ActiveXObject" in window) ? (
2024-11-14 09:01:37 +08:00
(agent.match(/msie\s(\d+)/) || [])[1] || '11' // 由于 ie11 并没有 msie 的标识
2023-03-10 16:39:21 +08:00
) : false;
}();
/**
* 获取 layui 常见方法以便用于组件单独版
*/
lay.layui = layui || {};
2024-11-14 09:01:37 +08:00
lay.getPath = layui.cache.dir; // 获取当前 JS 所在目录
lay.stope = layui.stope; // 中止冒泡
lay.each = function(){ // 遍历
2023-03-10 16:39:21 +08:00
layui.each.apply(layui, arguments);
return this;
};
2024-11-14 09:01:37 +08:00
2023-03-10 16:39:21 +08:00
2024-11-14 09:01:37 +08:00
// 数字前置补零
2023-03-10 16:39:21 +08:00
lay.digit = function(num, length){
if(!(typeof num === 'string' || typeof num === 'number')) return '';
var str = '';
num = String(num);
length = length || 2;
for(var i = num.length; i < length; i++){
str += '0';
}
return num < Math.pow(10, length) ? str + num : num;
};
2024-11-14 09:01:37 +08:00
// 创建元素
2023-03-10 16:39:21 +08:00
lay.elem = function(elemName, attr){
var elem = document.createElement(elemName);
lay.each(attr || {}, function(key, value){
elem.setAttribute(key, value);
});
return elem;
};
2024-11-14 09:01:37 +08:00
// 当前页面是否存在滚动条
2023-03-10 16:39:21 +08:00
lay.hasScrollbar = function(){
return document.body.scrollHeight > (window.innerHeight || document.documentElement.clientHeight);
};
2024-11-14 09:01:37 +08:00
// 元素定位
2023-03-10 16:39:21 +08:00
lay.position = function(elem, elemView, obj){
if(!elemView) return;
obj = obj || {};
2024-11-14 09:01:37 +08:00
// 如果绑定的是 document 或 body 元素,则直接获取鼠标坐标
2023-03-10 16:39:21 +08:00
if(elem === document || elem === lay('body')[0]){
obj.clickType = 'right';
}
2024-11-14 09:01:37 +08:00
// 绑定绑定元素的坐标
2023-03-10 16:39:21 +08:00
var rect = obj.clickType === 'right' ? function(){
var e = obj.e || window.event || {};
return {
left: e.clientX
,top: e.clientY
,right: e.clientX
,bottom: e.clientY
}
}() : elem.getBoundingClientRect()
2024-11-14 09:01:37 +08:00
,elemWidth = elemView.offsetWidth // 控件的宽度
,elemHeight = elemView.offsetHeight // 控件的高度
2023-03-10 16:39:21 +08:00
2024-11-14 09:01:37 +08:00
// 滚动条高度
2023-03-10 16:39:21 +08:00
,scrollArea = function(type){
type = type ? 'scrollLeft' : 'scrollTop';
return document.body[type] | document.documentElement[type];
}
2024-11-14 09:01:37 +08:00
// 窗口宽高
2023-03-10 16:39:21 +08:00
,winArea = function(type){
return document.documentElement[type ? 'clientWidth' : 'clientHeight']
}, margin = 5, left = rect.left, top = rect.bottom;
2024-11-14 09:01:37 +08:00
// 相对元素居中
2023-03-10 16:39:21 +08:00
if(obj.align === 'center'){
left = left - (elemWidth - elem.offsetWidth)/2;
} else if(obj.align === 'right'){
left = left - elemWidth + elem.offsetWidth;
}
2024-11-14 09:01:37 +08:00
// 判断右侧是否超出边界
2023-03-10 16:39:21 +08:00
if(left + elemWidth + margin > winArea('width')){
2024-11-14 09:01:37 +08:00
left = winArea('width') - elemWidth - margin; // 如果超出右侧,则将面板向右靠齐
2023-03-10 16:39:21 +08:00
}
2024-11-14 09:01:37 +08:00
// 左侧是否超出边界
2023-03-10 16:39:21 +08:00
if(left < margin) left = margin;
2024-11-14 09:01:37 +08:00
// 判断底部和顶部是否超出边界
2023-03-10 16:39:21 +08:00
if(top + elemHeight + margin > winArea()){
2024-11-14 09:01:37 +08:00
// 优先顶部是否有足够区域显示完全
2023-03-10 16:39:21 +08:00
if(rect.top > elemHeight + margin){
2024-11-14 09:01:37 +08:00
top = rect.top - elemHeight - margin*2; // 顶部有足够的区域显示
2023-03-10 16:39:21 +08:00
} else {
2024-11-14 09:01:37 +08:00
// 如果面板是鼠标右键弹出,且顶部没有足够区域显示,则将面板向底部靠齐
2023-03-10 16:39:21 +08:00
if(obj.clickType === 'right'){
top = winArea() - elemHeight - margin*2;
2024-11-14 09:01:37 +08:00
if(top < 0) top = 0; // 不能溢出窗口顶部
2023-03-10 16:39:21 +08:00
} else {
top = margin; // 位置计算逻辑完备性处理
}
}
}
2024-11-14 09:01:37 +08:00
// 定位类型
2023-03-10 16:39:21 +08:00
var position = obj.position;
if(position) elemView.style.position = position;
2024-11-14 09:01:37 +08:00
// 设置坐标
2023-03-10 16:39:21 +08:00
elemView.style.left = left + (position === 'fixed' ? 0 : scrollArea(1)) + 'px';
elemView.style.top = top + (position === 'fixed' ? 0 : scrollArea()) + 'px';
2024-11-14 09:01:37 +08:00
// 防止页面无滚动条时,又因为弹出面板而出现滚动条导致的坐标计算偏差
2023-03-10 16:39:21 +08:00
if(!lay.hasScrollbar()){
var rect1 = elemView.getBoundingClientRect();
2024-11-14 09:01:37 +08:00
// 如果弹出面板的溢出窗口底部,则表示将出现滚动条,此时需要重新计算坐标
2023-03-10 16:39:21 +08:00
if(!obj.SYSTEM_RELOAD && (rect1.bottom + margin) > winArea()){
obj.SYSTEM_RELOAD = true;
setTimeout(function(){
lay.position(elem, elemView, obj);
}, 50);
}
}
};
2024-11-14 09:01:37 +08:00
// 获取元素上的属性配置项
lay.options = function(elem, opts){
opts = typeof opts === 'object' ? opts : {attr: opts};
if(elem === document) return {};
var othis = lay(elem);
var attrName = opts.attr || 'lay-options';
var attrValue = othis.attr(attrName);
2023-03-10 16:39:21 +08:00
try {
2024-11-14 09:01:37 +08:00
return new Function('return '+ (attrValue || '{}'))();
2023-03-10 16:39:21 +08:00
} catch(ev) {
2024-11-14 09:01:37 +08:00
layui.hint().error(opts.errorText || [
attrName + '="'+ attrValue + '"',
'\n parseerror: '+ ev
].join('\n'), 'error');
2023-03-10 16:39:21 +08:00
return {};
}
};
2024-11-14 09:01:37 +08:00
// 元素是否属于顶级元素document 或 body
2023-03-10 16:39:21 +08:00
lay.isTopElem = function(elem){
var topElems = [document, lay('body')[0]]
,matched = false;
lay.each(topElems, function(index, item){
if(item === elem){
return matched = true
}
});
return matched;
};
2024-11-14 09:01:37 +08:00
/*
* lay 元素操作
*/
2023-03-10 16:39:21 +08:00
2024-11-14 09:01:37 +08:00
// 追加字符
Class.addStr = function(str, new_str){
2023-03-10 16:39:21 +08:00
str = str.replace(/\s+/, ' ');
new_str = new_str.replace(/\s+/, ' ').split(' ');
lay.each(new_str, function(ii, item){
if(!new RegExp('\\b'+ item + '\\b').test(str)){
str = str + ' ' + item;
}
});
return str.replace(/^\s|\s$/, '');
};
2024-11-14 09:01:37 +08:00
// 移除值
Class.removeStr = function(str, new_str){
2023-03-10 16:39:21 +08:00
str = str.replace(/\s+/, ' ');
new_str = new_str.replace(/\s+/, ' ').split(' ');
lay.each(new_str, function(ii, item){
var exp = new RegExp('\\b'+ item + '\\b')
if(exp.test(str)){
str = str.replace(exp, '');
}
});
return str.replace(/\s+/, ' ').replace(/^\s|\s$/, '');
};
2024-11-14 09:01:37 +08:00
// 查找子元素
Class.fn.find = function(selector){
2023-03-10 16:39:21 +08:00
var that = this;
2024-11-14 09:01:37 +08:00
var elem = [];
var isObject = typeof selector === 'object';
2023-03-10 16:39:21 +08:00
this.each(function(i, item){
2024-11-14 09:01:37 +08:00
var children = isObject && item.contains(selector)
? selector
: item.querySelectorAll(selector || null);
lay.each(children, function(index, child){
elem.push(child);
});
2023-03-10 16:39:21 +08:00
});
2024-11-14 09:01:37 +08:00
return lay(elem);
2023-03-10 16:39:21 +08:00
};
2024-11-14 09:01:37 +08:00
// 元素遍历
Class.fn.each = function(fn){
2023-03-10 16:39:21 +08:00
return lay.each.call(this, this, fn);
};
2024-11-14 09:01:37 +08:00
// 添加 className
Class.fn.addClass = function(className, type){
2023-03-10 16:39:21 +08:00
return this.each(function(index, item){
2024-11-14 09:01:37 +08:00
item.className = Class[type ? 'removeStr' : 'addStr'](item.className, className)
2023-03-10 16:39:21 +08:00
});
};
2024-11-14 09:01:37 +08:00
// 移除 className
Class.fn.removeClass = function(className){
2023-03-10 16:39:21 +08:00
return this.addClass(className, true);
};
2024-11-14 09:01:37 +08:00
// 是否包含 css 类
Class.fn.hasClass = function(className){
2023-03-10 16:39:21 +08:00
var has = false;
this.each(function(index, item){
if(new RegExp('\\b'+ className +'\\b').test(item.className)){
has = true;
}
});
return has;
};
2024-11-14 09:01:37 +08:00
// 添加或获取 css style
Class.fn.css = function(key, value){
var that = this;
var parseValue = function(v){
2023-03-10 16:39:21 +08:00
return isNaN(v) ? v : (v +'px');
};
return (typeof key === 'string' && value === undefined) ? function(){
if(that.length > 0) return that[0].style[key];
}() : that.each(function(index, item){
typeof key === 'object' ? lay.each(key, function(thisKey, thisValue){
item.style[thisKey] = parseValue(thisValue);
}) : item.style[key] = parseValue(value);
});
};
2024-11-14 09:01:37 +08:00
// 添加或获取宽度
Class.fn.width = function(value){
2023-03-10 16:39:21 +08:00
var that = this;
return value === undefined ? function(){
2024-11-14 09:01:37 +08:00
if(that.length > 0) return that[0].offsetWidth; // 此处还需做兼容
2023-03-10 16:39:21 +08:00
}() : that.each(function(index, item){
that.css('width', value);
});
};
2024-11-14 09:01:37 +08:00
// 添加或获取高度
Class.fn.height = function(value){
2023-03-10 16:39:21 +08:00
var that = this;
return value === undefined ? function(){
2024-11-14 09:01:37 +08:00
if(that.length > 0) return that[0].offsetHeight; // 此处还需做兼容
2023-03-10 16:39:21 +08:00
}() : that.each(function(index, item){
that.css('height', value);
});
};
2024-11-14 09:01:37 +08:00
// 添加或获取属性
Class.fn.attr = function(key, value){
2023-03-10 16:39:21 +08:00
var that = this;
return value === undefined ? function(){
if(that.length > 0) return that[0].getAttribute(key);
}() : that.each(function(index, item){
item.setAttribute(key, value);
});
};
2024-11-14 09:01:37 +08:00
// 移除属性
Class.fn.removeAttr = function(key){
2023-03-10 16:39:21 +08:00
return this.each(function(index, item){
item.removeAttribute(key);
});
};
2024-11-14 09:01:37 +08:00
// 设置或获取 HTML 内容
Class.fn.html = function(html){
2023-03-10 16:39:21 +08:00
var that = this;
return html === undefined ? function(){
if(that.length > 0) return that[0].innerHTML;
}() : this.each(function(index, item){
item.innerHTML = html;
});
};
2024-11-14 09:01:37 +08:00
// 设置或获取值
Class.fn.val = function(value){
2023-03-10 16:39:21 +08:00
var that = this;
return value === undefined ? function(){
if(that.length > 0) return that[0].value;
}() : this.each(function(index, item){
item.value = value;
});
};
2024-11-14 09:01:37 +08:00
// 追加内容
Class.fn.append = function(elem){
2023-03-10 16:39:21 +08:00
return this.each(function(index, item){
typeof elem === 'object'
? item.appendChild(elem)
: item.innerHTML = item.innerHTML + elem;
});
};
2024-11-14 09:01:37 +08:00
// 移除内容
Class.fn.remove = function(elem){
2023-03-10 16:39:21 +08:00
return this.each(function(index, item){
elem ? item.removeChild(elem) : item.parentNode.removeChild(item);
});
};
2024-11-14 09:01:37 +08:00
// 事件绑定
Class.fn.on = function(eventName, fn){
2023-03-10 16:39:21 +08:00
return this.each(function(index, item){
item.attachEvent ? item.attachEvent('on' + eventName, function(e){
e.target = e.srcElement;
fn.call(item, e);
}) : item.addEventListener(eventName, fn, false);
});
};
2024-11-14 09:01:37 +08:00
// 解除事件
Class.fn.off = function(eventName, fn){
2023-03-10 16:39:21 +08:00
return this.each(function(index, item){
item.detachEvent
? item.detachEvent('on'+ eventName, fn)
: item.removeEventListener(eventName, fn, false);
});
};
2024-11-14 09:01:37 +08:00
// export
2023-03-10 16:39:21 +08:00
window.lay = lay;
2024-11-14 09:01:37 +08:00
// 输出为 layui 模块
2023-03-10 16:39:21 +08:00
if(window.layui && layui.define){
2024-11-14 09:01:37 +08:00
layui.define(function(exports){
2023-03-10 16:39:21 +08:00
exports(MOD_NAME, lay);
});
}
2024-11-14 09:01:37 +08:00
}(window, window.document); // gulp build: lay-footer