From be5c58ef6f4c68219dd2528ffad839e89fb49d0b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E8=B4=A4=E5=BF=83?=
<3277200+sentsim@users.noreply.github.com>
Date: Fri, 17 Nov 2023 09:57:59 +0800
Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=20`lay.options()`=20?=
=?UTF-8?q?=E6=96=B9=E6=B3=95=E4=BD=BF=E7=94=A8=E7=9A=84=E5=AE=89=E5=85=A8?=
=?UTF-8?q?=E6=8F=90=E7=A4=BA=E6=B3=A8=E9=87=8A?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
src/modules/lay.js | 138 +++++++++++++++++++++++----------------------
1 file changed, 71 insertions(+), 67 deletions(-)
diff --git a/src/modules/lay.js b/src/modules/lay.js
index 1de15716..66adadeb 100644
--- a/src/modules/lay.js
+++ b/src/modules/lay.js
@@ -3,18 +3,18 @@
;!function(window){ // gulp build: lay-header
"use strict";
-
+
var MOD_NAME = 'lay'; // 模块名
var document = window.document;
-
+
/**
* 元素查找
- * @param {string | HTMLElement | JQuery} selector
+ * @param {string | HTMLElement | JQuery} selector
*/
- var lay = function(selector){
+ var lay = function(selector){
return new Class(selector);
};
-
+
// 构造器
var Class = function(selector){
var that = this;
@@ -45,11 +45,11 @@
});
return rst;
};
-
+
/*
lay 对象操作
*/
-
+
Class.fn = Class.prototype = [];
Class.fn.constructor = Class;
@@ -86,7 +86,7 @@
}
return args[0];
};
-
+
/**
* IE 版本
* @type {string | boolean} - 如果是 IE 返回版本字符串,否则返回 false
@@ -97,12 +97,12 @@
(agent.match(/msie\s(\d+)/) || [])[1] || '11' // 由于 ie11 并没有 msie 的标识
) : false;
}();
-
-
- /**
+
+
+ /**
* 获取 layui 常见方法,以便用于组件单独版
*/
-
+
lay.layui = layui || {};
lay.getPath = layui.cache.dir; // 获取当前 JS 所在目录
lay.stope = layui.stope; // 中止冒泡
@@ -134,7 +134,7 @@
}
return num < Math.pow(10, length) ? str + num : num;
};
-
+
/**
* 创建元素
* @param {string} elemName - 元素的标签名
@@ -156,7 +156,7 @@
/**
* 当前页面是否存在滚动条
* @returns {boolean} 是否存在滚动条
- * @example
+ * @example
* ```
* lay.hasScrollbar() // true 或 false
* ```
@@ -180,7 +180,7 @@
* color: green;
* }
*
- *
+ *
* lay.getStyleRules($('#test')[0], function(rule, index){
* if(rule.selectorText === '.lay-card'){
* console.log(index, rule.cssText) // 0 '.lay-card{color: #000}'
@@ -211,14 +211,14 @@
* @param {string | HTMLElement | JQuery} [options.target] - 目标容器,指定后会将样式追加到目标容器
* @param {string} [options.id] - 样式元素的 id,默认自增
* @param {string} options.text - 样式内容
- * @returns {HTMLStyleElement} 返回创建的样式元素
+ * @returns {HTMLStyleElement} 返回创建的样式元素
* @example
* ```html
*
*
*
*
- *
+ *
* lay.style({
* target: '#targetEl',
* text: '.card{color: #000}'
@@ -231,9 +231,9 @@
var style = lay.elem('style');
var styleText = options.text || '';
var target = options.target;
-
+
if (!styleText) return;
-
+
// 添加样式
if ('styleSheet' in style) {
style.setAttribute('type', 'text/css');
@@ -241,7 +241,7 @@
} else {
style.innerHTML = styleText;
}
-
+
// ID
style.id = 'LAY-STYLE-'+ (options.id || function(index) {
lay.style.index++;
@@ -257,7 +257,7 @@
return style;
};
-
+
/**
* 将元素定位到指定目标元素附近
* @param {HTMLElement} target - 目标元素
@@ -277,13 +277,13 @@
* 菜单1
* 菜单2
*
- *
+ *
* // 下拉菜单将被定位到按钮附近
* lay.position(
- * $('#targetEl')[0],
- * $('#contentEl')[0],
+ * $('#targetEl')[0],
+ * $('#contentEl')[0],
* {
- * position: 'fixed',
+ * position: 'fixed',
* align: 'center'
* }
* )
@@ -292,7 +292,7 @@
lay.position = function(target, elem, opts){
if(!elem) return;
opts = opts || {};
-
+
// 如果绑定的是 document 或 body 元素,则直接获取鼠标坐标
if(target === document || target === lay('body')[0]){
opts.clickType = 'right';
@@ -310,13 +310,13 @@
}() : target.getBoundingClientRect();
var elemWidth = elem.offsetWidth; // 控件的宽度
var elemHeight = elem.offsetHeight; // 控件的高度
-
+
// 滚动条高度
var scrollArea = function(type){
type = type ? 'scrollLeft' : 'scrollTop';
return document.body[type] | document.documentElement[type];
};
-
+
// 窗口宽高
var winArea = function(type){
return document.documentElement[type ? 'clientWidth' : 'clientHeight']
@@ -324,7 +324,7 @@
var margin = 'margin' in opts ? opts.margin : 5;
var left = rect.left;
var top = rect.bottom;
-
+
// 相对元素居中
if(opts.align === 'center'){
left = left - (elemWidth - target.offsetWidth) / 2;
@@ -338,7 +338,7 @@
}
// 左侧是否超出边界
if(left < margin) left = margin;
-
+
// 判断底部和顶部是否超出边界
if(rect.bottom + elemHeight + margin > winArea()){ // 底部超出边界
@@ -366,11 +366,11 @@
}
}
*/
-
+
// 定位类型
var position = opts.position;
if(position) elem.style.position = position;
-
+
// 设置坐标
elem.style.left = left + (position === 'fixed' ? 0 : scrollArea(1)) + 'px';
elem.style.top = top + (position === 'fixed' ? 0 : scrollArea()) + 'px';
@@ -387,7 +387,7 @@
}
}
};
-
+
/**
* 获取元素上的属性配置项
* @param {string | HTMLElement | JQuery} elem - HTML 元素
@@ -396,14 +396,14 @@
* @example
* ```js
*
- *
+ *
* var elem = $('#testEl')
* lay.options(elem) // {color:red}
* lay.options(elem[0]) // {color:red}
* lay.options('#testEl') // {color:red}
* lay.options('#testEl', {attr: 'lay-toc'}) // {hot: true}
* lay.options('#testEl', 'lay-toc') // {hot: true}
- *
+ *
* $('#testEl').attr('lay-toc') // '{hot: true}'
* ```
*/
@@ -417,16 +417,20 @@
var attrValue = othis.attr(attrName);
try {
+ /**
+ * 请注意: 开发者在使用 lay-options="{}" 配置组件选项时,需确保属性值不来自于网页用户,
+ * 即属性值必须在网页开发者自身的可控范围内,否则请勿在 HTML 标签属性中获取组件选项。
+ */
return new Function('return '+ (attrValue || '{}'))();
} catch(ev) {
layui.hint().error(opts.errorText || [
- attrName + '="'+ attrValue + '"',
+ attrName + '="'+ attrValue + '"',
'\n parseerror: '+ ev
].join('\n'), 'error');
return {};
}
};
-
+
/**
* 元素是否属于顶级元素(document 或 body)
@@ -485,7 +489,7 @@
elem.style.opacity = '0';
elem.style.top = '0px';
elem.style.left = '0px';
-
+
document.body.appendChild(elem);
elem.select();
@@ -505,7 +509,7 @@
/*
* lay 元素操作
*/
-
+
// 追加字符
Class.addStr = function(str, new_str){
@@ -518,7 +522,7 @@
});
return str.replace(/^\s|\s$/, '');
};
-
+
// 移除值
Class.removeStr = function(str, new_str){
str = str.replace(/\s+/, ' ');
@@ -531,7 +535,7 @@
});
return str.replace(/\s+/, ' ').replace(/^\s|\s$/, '');
};
-
+
// 查找子元素
Class.fn.find = function(selector){
var that = this;
@@ -539,7 +543,7 @@
var isObject = typeof selector === 'object';
this.each(function(i, item){
- var children = isObject && item.contains(selector)
+ var children = isObject && item.contains(selector)
? selector
: item.querySelectorAll(selector || null);
@@ -550,24 +554,24 @@
return lay(elem);
};
-
+
// 元素遍历
Class.fn.each = function(fn){
return lay.each.call(this, this, fn);
};
-
+
// 添加 className
Class.fn.addClass = function(className, type){
return this.each(function(index, item){
item.className = Class[type ? 'removeStr' : 'addStr'](item.className, className)
});
};
-
+
// 移除 className
Class.fn.removeClass = function(className){
return this.addClass(className, true);
};
-
+
// 是否包含 css 类
Class.fn.hasClass = function(className){
var has = false;
@@ -578,7 +582,7 @@
});
return has;
};
-
+
// 添加或获取 css style
Class.fn.css = function(key, value){
var that = this;
@@ -591,9 +595,9 @@
typeof key === 'object' ? lay.each(key, function(thisKey, thisValue){
item.style[thisKey] = parseValue(thisValue);
}) : item.style[key] = parseValue(value);
- });
+ });
};
-
+
// 添加或获取宽度
Class.fn.width = function(value){
var that = this;
@@ -601,9 +605,9 @@
if(that.length > 0) return that[0].offsetWidth; // 此处还需做兼容
}() : that.each(function(index, item){
that.css('width', value);
- });
+ });
};
-
+
// 添加或获取高度
Class.fn.height = function(value){
var that = this;
@@ -611,9 +615,9 @@
if(that.length > 0) return that[0].offsetHeight; // 此处还需做兼容
}() : that.each(function(index, item){
that.css('height', value);
- });
+ });
};
-
+
// 添加或获取属性
Class.fn.attr = function(key, value){
var that = this;
@@ -621,16 +625,16 @@
if(that.length > 0) return that[0].getAttribute(key);
}() : that.each(function(index, item){
item.setAttribute(key, value);
- });
+ });
};
-
+
// 移除属性
Class.fn.removeAttr = function(key){
return this.each(function(index, item){
item.removeAttribute(key);
});
};
-
+
// 设置或获取 HTML 内容
Class.fn.html = function(html){
var that = this;
@@ -640,7 +644,7 @@
item.innerHTML = html;
});
};
-
+
// 设置或获取值
Class.fn.val = function(value){
var that = this;
@@ -650,23 +654,23 @@
item.value = value;
});
};
-
+
// 追加内容
Class.fn.append = function(elem){
return this.each(function(index, item){
- typeof elem === 'object'
+ typeof elem === 'object'
? item.appendChild(elem)
: item.innerHTML = item.innerHTML + elem;
});
};
-
+
// 移除内容
Class.fn.remove = function(elem){
return this.each(function(index, item){
elem ? item.removeChild(elem) : item.parentNode.removeChild(item);
});
};
-
+
// 事件绑定
Class.fn.on = function(eventName, fn){
return this.each(function(index, item){
@@ -676,24 +680,24 @@
}) : item.addEventListener(eventName, fn, false);
});
};
-
+
// 解除事件
Class.fn.off = function(eventName, fn){
return this.each(function(index, item){
- item.detachEvent
- ? item.detachEvent('on'+ eventName, fn)
+ item.detachEvent
+ ? item.detachEvent('on'+ eventName, fn)
: item.removeEventListener(eventName, fn, false);
});
};
-
+
// export
window.lay = lay;
-
+
// 输出为 layui 模块
if(window.layui && layui.define){
layui.define(function(exports){
exports(MOD_NAME, lay);
});
}
-
+
}(window, window.document); // gulp build: lay-footer