import { DOMUtils } from "@/env";
class LoadingView {
config: {
className: string;
textClassName: string;
iconClassName: string;
outSideClassName: string;
withInClassName: string;
};
loadingViewElement?: HTMLDivElement;
loadingViewHTML: string;
loadingViewIconHTML: string;
/**
*
* @param withIcon 是否添加icon
* @param isEnd icon是否添加在后面
*/
constructor(withIcon?: boolean, isEnd?: boolean) {
this.config = {
className: "gm-load-view",
textClassName: "gm-load-view-text",
iconClassName: "gm-load-view-icon",
outSideClassName: "gm-load-view-icon-outside",
withInClassName: "gm-load-view-icon-within",
};
this.loadingViewElement = void 0;
this.loadingViewHTML = /*html*/ `
Loading...
`.trim();
this.loadingViewIconHTML = /*html*/ `
`.trim();
this.addStyle();
this.initLoadingView(withIcon, isEnd);
}
/**
* 加载需要的CSS
*/
addStyle() {
if (this.isExistsCSS()) {
return;
}
const cssText = /*css*/ `
.${this.config.className}{
margin: 0.08rem;
background: #fff;
font-size: 15px;
text-align: center;
width: inherit;
border-radius: 0.12rem;
}
.${this.config.iconClassName}{
width: 45px;
}
.${this.config.className},
.${this.config.iconClassName}{
height: 45px;
line-height: 45px;
display: flex;
align-items: center;
justify-content: center;
}
.${this.config.outSideClassName},
.${this.config.withInClassName}{
position: absolute;
margin-left: 140px;
border: 5px solid rgba(0, 183, 229, 0.9);
opacity: .9;
border-radius: 50px;
width: 20px;
height: 20px;
margin: 0 auto;
}
.${this.config.outSideClassName}{
background-color: rgba(0, 0, 0, 0);
border-right: 5px solid rgba(0, 0, 0, 0);
border-left: 5px solid rgba(0, 0, 0, 0);
box-shadow: 0 0 35px #2187e7;
-moz-animation: spinPulse 1s infinite ease-in-out;
-webkit-animation: spinPulse 1s infinite ease-in-out;
-o-animation: spinPulse 1s infinite ease-in-out;
-ms-animation: spinPulse 1s infinite ease-in-out;
}
.${this.config.withInClassName}{
background: rgba(0, 0, 0, 0) no-repeat center center;
border-top: 5px solid rgba(0, 0, 0, 0);
border-bottom: 5px solid rgba(0, 0, 0, 0);
box-shadow: 0 0 15px #2187e7;
-moz-animation: spinoffPulse 3s infinite linear;
-webkit-animation: spinoffPulse 3s infinite linear;
-o-animation: spinoffPulse 3s infinite linear;
-ms-animation: spinoffPulse 3s infinite linear;
}
@-moz-keyframes spinPulse{0%{-moz-transform:rotate(160deg);opacity:0;box-shadow:0 0 1px #505050}
50%{-moz-transform:rotate(145deg);opacity:1}
100%{-moz-transform:rotate(-320deg);opacity:0}
}
@-moz-keyframes spinoffPulse{0%{-moz-transform:rotate(0)}
100%{-moz-transform:rotate(360deg)}
}
@-webkit-keyframes spinPulse{0%{-webkit-transform:rotate(160deg);opacity:0;box-shadow:0 0 1px #505050}
50%{-webkit-transform:rotate(145deg);opacity:1}
100%{-webkit-transform:rotate(-320deg);opacity:0}
}
@-webkit-keyframes spinoffPulse{0%{-webkit-transform:rotate(0)}
100%{-webkit-transform:rotate(360deg)}
}
@-o-keyframes spinPulse{0%{-o-transform:rotate(160deg);opacity:0;box-shadow:0 0 1px #505050}
50%{-o-transform:rotate(145deg);opacity:1}
100%{-o-transform:rotate(-320deg);opacity:0}
}
@-o-keyframes spinoffPulse{0%{-o-transform:rotate(0)}
100%{-o-transform:rotate(360deg)}
}
@-ms-keyframes spinPulse{0%{-ms-transform:rotate(160deg);opacity:0;box-shadow:0 0 1px #505050}
50%{-ms-transform:rotate(145deg);opacity:1}
100%{-ms-transform:rotate(-320deg);opacity:0}
}
@-ms-keyframes spinoffPulse{0%{-ms-transform:rotate(0)}
100%{-ms-transform:rotate(360deg)}
}
`;
const $style = DOMUtils.addStyle(cssText);
$style.setAttribute("data-from", "loadingView");
$style.setAttribute("type", "text/css");
}
/**
* 获取LoadingView元素
*/
get $el() {
return this.getLoadingViewElement();
}
/**
* 获取实例化的loadingView的icon元素
*/
get $icon() {
return this.getIconElement();
}
/**
* 初始化loadingView元素
* @param withIcon 是否添加icon
* @param isEnd icon是否添加在后面
*/
initLoadingView(withIcon: boolean = false, isEnd: boolean = true) {
this.setLoadingViewElement();
const $wrapper = DOMUtils.createElement("div", {
innerHTML: this.loadingViewHTML,
});
const $wrapperFirst = $wrapper.firstChild as HTMLDivElement;
if (withIcon) {
const $iconWrapper = DOMUtils.createElement("div", {
innerHTML: this.loadingViewIconHTML,
});
if (isEnd) {
$wrapperFirst.appendChild($iconWrapper.firstChild as HTMLDivElement);
} else {
$wrapperFirst.insertBefore($iconWrapper.firstChild as HTMLDivElement, $wrapperFirst.firstChild);
}
}
this.setLoadingViewElement($wrapperFirst);
return $wrapperFirst;
}
/**
* 设置LoadingView
* @param element
*/
setLoadingViewElement(element?: HTMLDivElement) {
this.loadingViewElement = element;
}
/**
* 获取LoadingView元素
*/
getLoadingViewElement() {
if (!this.loadingViewElement) {
throw new TypeError("object loadingViewElement is null");
}
return this.loadingViewElement;
}
/**
* 获取实例化的loadingView的icon元素
*/
getIconElement() {
return this.$el.querySelector("." + this.config.iconClassName) as HTMLElement | null;
}
/**
* 显示LoadingView
*/
show() {
DOMUtils.show(this.$el, false);
}
/**
* 隐藏LoadingView
*/
hide() {
DOMUtils.hide(this.$el, false);
}
/**
* 显示icon
*/
showIcon() {
const $icon = this.$icon;
if ($icon) {
DOMUtils.show($icon, false);
}
}
/**
* 隐藏icon
*/
hideIcon() {
const $icon = this.$icon;
if ($icon) {
DOMUtils.hide($icon, false);
}
}
/**
* 设置文本
* @param text 文本
* @param withIcon 是否设置Icon图标
* @param isEnd icon是否添加在后面
*/
setText(text: string, withIcon: boolean = false, isEnd: boolean = true) {
DOMUtils.html(this.$el, `${text}`);
if (withIcon) {
let $icon = this.$icon;
if (!$icon) {
const $wrapper = DOMUtils.createElement("div", {
innerHTML: this.loadingViewIconHTML,
});
$icon = $wrapper.firstChild as HTMLDivElement;
if (isEnd) {
this.$el.appendChild($icon);
} else {
this.$el.insertBefore($icon, this.$el.firstChild);
}
}
this.showIcon();
} else {
this.$icon?.remove();
}
}
/**
* 设置超文本
* @param text 文本
*/
setHTML(text: string) {
DOMUtils.html(this.$el, text);
}
/**
* 删除Loading元素
*/
destory() {
this.$el?.remove();
this.setLoadingViewElement();
}
/**
* 删除页面中所有的loadingView
*/
removeAll() {
document.querySelectorAll("." + this.config.className).forEach(($it) => $it.remove());
}
/**
* 判断Loading是否已加载到页面中
*/
isExists() {
return !!document.querySelector(`.${this.config.className}`);
}
/**
* 判断Loading是否存在Loading图标
*/
isExistsIcon() {
return !!this.$icon;
}
/**
* 判断Loading中的文本是否存在
*/
isExistsText() {
return !!this.$el.querySelector(`.${this.config.textClassName}`);
}
/**
* 判断页面中是否存在CSS的style
*/
isExistsCSS() {
return !!document.querySelector("style[data-from='loadingView'][type='text/css']");
}
}
export { LoadingView };