lu2
Version:
Simple and flexible UI component library based on native HTML and JavaScript
189 lines (153 loc) • 4.78 kB
JavaScript
/**
* @Float.js
* @author zhangxinxu
* @version
* @description 自动隐藏的浮层显示元素
* @created 22-06-06
*/
class UiFloat extends HTMLElement {
static get observedAttributes () {
return ['open'];
}
constructor () {
super();
if (arguments.length) {
UiFloat.custom.apply(this, arguments);
}
}
get type () {
return this.getAttribute('type');
}
get time () {
let strTime = this.getAttribute('time');
if (!isNaN(strTime) && !isNaN(parseFloat(strTime))) {
return Number(strTime);
}
return 3000;
}
set type (value) {
this.setAttribute('type', value);
}
set time (value) {
this.setAttribute('time', value);
}
get open () {
return this.hasAttribute('open');
}
set open (value) {
this.toggleAttribute('open', value);
}
connectedCallback () {
if (!this.closeMode) {
this.closeMode = 'hide';
}
// 点击组件本身或按键盘 esc/enter 键即可关闭组件
this.addEventListener('click', () => {
// 移除元素
this[this.closeMode]();
});
// 全局事件
this.dispatchEvent(new CustomEvent('connected', {
detail: {
type: 'ui-float'
}
}));
this.isConnectedCallback = true;
}
attributeChangedCallback (name, oldValue, newValue) {
// 让按钮或者之前的触发元素重新获取焦点,便于继续操作
if (name == 'open' && typeof oldValue !== typeof newValue) {
if (typeof newValue === 'string') {
clearTimeout(this.timer);
if (this.time) {
this.timer = setTimeout(() => {
this[this.closeMode]();
this.position();
}, this.time);
}
this.setAttribute('data-tid', this.timer);
// 组件的 z-index 层级计算
this.zIndex();
// 组件的定位,不同的提示位置不重叠
this.position();
}
}
}
zIndex () {
// 只对<body>子元素进行层级最大化计算处理,这里float默认的z-index值是19
var numZIndexNew = 19;
this.parentElement && [...this.parentElement.childNodes].forEach(function (eleChild) {
if (eleChild.nodeType != 1) {
return;
}
var objStyleChild = window.getComputedStyle(eleChild);
var numZIndexChild = objStyleChild.zIndex * 1;
if (numZIndexChild && objStyleChild.display != 'none') {
numZIndexNew = Math.max(numZIndexChild + 1, numZIndexNew);
}
});
this.style.zIndex = numZIndexNew;
}
// 定位处理
position () {}
// 调用方法处理
static custom (text = '', type, time) {
// 如果是静态方法执行
// 创建ui-float自定义元素
if (!this.matches || !this.matches('ui-float')) {
return UiFloat.custom.apply(document.createElement('ui-float'), arguments);
}
if (typeof text == 'object') {
type = text;
text = '';
}
if (typeof text != 'string') {
return this;
}
this.closeMode = 'remove';
// 如果传入的类型是object形式
if (type && typeof type === 'object') {
UiFloat.custom.call(this, text, type.type, type.time);
return;
}
// 如果type的类型是number,则赋值给time
if (typeof type === 'number') {
UiFloat.custom.call(this, text, time, type);
return;
}
if (time || time === 0) {
this.time = time;
}
if (type) {
this.type = type;
}
this.innerHTML = text;
// append 内存中创建的 <ui-float> 元素
if (!this.parentElement) {
document.body.appendChild(this);
this.dispatchEvent(new CustomEvent('DOMContentLoaded'));
}
this.show();
return this;
}
remove () {
if (this.parentElement) {
this.parentElement.removeChild(this);
}
this.open = false;
}
show () {
if (this.time > 0) {
this.open = true;
}
}
hide () {
this.open = false;
}
}
if (!customElements.get('ui-float')) {
customElements.define('ui-float', UiFloat);
}
// 将该方法定义为 window 全局使用的方法
window.UiFloat = UiFloat;
/**/export default UiFloat;