|
@@ -3,10 +3,20 @@ function lt(obj) {
|
|
console.table(JSON.parse(JSON.stringify(obj)));
|
|
console.table(JSON.parse(JSON.stringify(obj)));
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+/**
|
|
|
|
+ * 深度克隆
|
|
|
|
+ * @param obj
|
|
|
|
+ * @returns {any}
|
|
|
|
+ */
|
|
function deepClone(obj) {
|
|
function deepClone(obj) {
|
|
return JSON.parse(JSON.stringify(obj))
|
|
return JSON.parse(JSON.stringify(obj))
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+/**
|
|
|
|
+ * 日期格式化 new Date().format('yyyy-MM-dd hh:mm:ss')
|
|
|
|
+ * @param fmt
|
|
|
|
+ * @returns {*}
|
|
|
|
+ */
|
|
Date.prototype.format = function (fmt) {
|
|
Date.prototype.format = function (fmt) {
|
|
const o = {
|
|
const o = {
|
|
"M+": this.getMonth() + 1, //月份
|
|
"M+": this.getMonth() + 1, //月份
|
|
@@ -37,40 +47,332 @@ axios.interceptors.response.use(function (response) {
|
|
return Promise.reject(error);
|
|
return Promise.reject(error);
|
|
});
|
|
});
|
|
|
|
|
|
-// 提醒
|
|
|
|
-function my_tip(string) {
|
|
|
|
- const div = document.createElement("div");
|
|
|
|
- div.setAttribute("id", "my_alert_danger");
|
|
|
|
- div.setAttribute("style", "position: fixed; width: 30%; left: 50%; top: 50%; transform: translate(-50%, -50%); z-index: 2000; background-color:green");
|
|
|
|
- div.innerHTML = string;
|
|
|
|
|
|
+/**
|
|
|
|
+ * 远程请求
|
|
|
|
+ * @type {{async: (function(*, *, *, *): Promise<unknown>), xhr_send: request.xhr_send, sync: (function(*, *, *, *): any)}}
|
|
|
|
+ */
|
|
|
|
+const request = {
|
|
|
|
+ xhr_send: function (xhr, method, headers, data) {
|
|
|
|
+ if (headers) {
|
|
|
|
+ for (const key in headers) {
|
|
|
|
+ xhr.setRequestHeader(key, headers[key]);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (method.match(/^(POST|PUT)$/i)) {
|
|
|
|
+ if (!headers || headers.indexOf("Content-Type") <= 0) {
|
|
|
|
+ xhr.setRequestHeader('Content-Type', 'application/json');
|
|
|
|
+ }
|
|
|
|
+ xhr.send(JSON.stringify(data));
|
|
|
|
+ } else {
|
|
|
|
+ xhr.send();
|
|
|
|
+ }
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 异步请求:request.async('https://jsonplaceholder.typicode.com/posts/1', 'GET', null, null)
|
|
|
|
+ * .then(data => console.log(data))
|
|
|
|
+ * .catch(error => console.error(error));
|
|
|
|
+ */
|
|
|
|
+ async: function (url, method, data, headers) {
|
|
|
|
+ return new Promise((resolve, reject) => {
|
|
|
|
+ const xhr = new XMLHttpRequest();
|
|
|
|
+ xhr.open(method, url, true);
|
|
|
|
+ this.xhr_send(xhr, method, headers, data);
|
|
|
|
+ xhr.onload = () => {
|
|
|
|
+ resolve(JSON.parse(xhr.responseText));
|
|
|
|
+ };
|
|
|
|
+ xhr.onerror = () => reject(xhr.statusText);
|
|
|
|
+ });
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 同步请求 let a = request.sync("https://httpbin.tianyunperfect.cn/ip","GET",null,null)
|
|
|
|
+ */
|
|
|
|
+ sync: function (url, method, data, headers) {
|
|
|
|
+ const xhr = new XMLHttpRequest();
|
|
|
|
+ xhr.open(method, url, false);
|
|
|
|
+ this.xhr_send(xhr, method, headers, data);
|
|
|
|
+ return JSON.parse(xhr.responseText);
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+/**
|
|
|
|
+ * 休眠一段时间: await sleep(2000)
|
|
|
|
+ * @param time
|
|
|
|
+ * @returns {Promise<unknown>}
|
|
|
|
+ */
|
|
|
|
+function sleep(time) {
|
|
|
|
+ return new Promise((resolve) => setTimeout(resolve, time));
|
|
|
|
+}
|
|
|
|
|
|
- document.body.prepend(div);
|
|
|
|
|
|
+/**
|
|
|
|
+ * 根据选择器 选择某一个dom,10秒钟内
|
|
|
|
+ * @param sel
|
|
|
|
+ * @returns {Promise<*>}
|
|
|
|
+ */
|
|
|
|
+async function getDom(sel) {
|
|
|
|
+ for (let i = 0; i < 100; i++) {
|
|
|
|
+ let dom = document.querySelector(sel);
|
|
|
|
+ if (dom) {
|
|
|
|
+ return dom;
|
|
|
|
+ } else {
|
|
|
|
+ await sleep(100);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
|
|
- setTimeout(() => {
|
|
|
|
- const element = document.getElementById("my_alert_danger");
|
|
|
|
- if (element) {
|
|
|
|
- element.parentNode.removeChild(element);
|
|
|
|
|
|
+/**
|
|
|
|
+ * 根据选择器 选择所有dom,10秒钟内
|
|
|
|
+ * @param sel
|
|
|
|
+ * @returns {Promise<*>}
|
|
|
|
+ */
|
|
|
|
+async function getDomAll(sel) {
|
|
|
|
+ for (let i = 0; i < 100; i++) {
|
|
|
|
+ let dom = document.querySelectorAll(sel);
|
|
|
|
+ if (dom.length > 0) {
|
|
|
|
+ return dom;
|
|
|
|
+ } else {
|
|
|
|
+ await sleep(100);
|
|
}
|
|
}
|
|
- }, 2000)
|
|
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/**
|
|
|
|
+ * 添加全局样式: addGlobalStyle('.box {height: 100px !important;}');
|
|
|
|
+ */
|
|
|
|
+function addGlobalStyle(newStyle) {
|
|
|
|
+ let styleElement = document.getElementById('styles_js');
|
|
|
|
+ if (!styleElement) {
|
|
|
|
+ styleElement = document.createElement('style');
|
|
|
|
+ styleElement.type = 'text/css';
|
|
|
|
+ styleElement.id = 'styles_js';
|
|
|
|
+ document.getElementsByTagName('head')[0].appendChild(styleElement);
|
|
|
|
+ }
|
|
|
|
+ styleElement.appendChild(document.createTextNode(newStyle));
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/**
|
|
|
|
+ * 获取 指定 name 的 url 参数
|
|
|
|
+ * @param url
|
|
|
|
+ * @param name
|
|
|
|
+ * @returns {string|string}
|
|
|
|
+ */
|
|
|
|
+function getQueryStringByUrl(url, name) {
|
|
|
|
+ let reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)", "i");
|
|
|
|
+ let r = url.substring(url.indexOf('?') + 1).match(reg); //获取url中"?"符后的字符串并正则匹配
|
|
|
|
+ let context = "";
|
|
|
|
+ if (r != null)
|
|
|
|
+ context = r[2];
|
|
|
|
+ reg = null;
|
|
|
|
+ r = null;
|
|
|
|
+ return context == null || context === "" || context === "undefined" ? "" : decodeURI(context);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+/**
|
|
|
|
+ * 获取 指定 name 的 url 参数
|
|
|
|
+ * @param name
|
|
|
|
+ * @returns {string}
|
|
|
|
+ */
|
|
|
|
+function getQueryString(name) {
|
|
|
|
+ return getQueryStringByUrl(location.href, name);
|
|
}
|
|
}
|
|
|
|
|
|
-// 发送同步请求 let a = sendSyncRequest("https://httpbin.tianyunperfect.cn/ip","GET",null,null)
|
|
|
|
-function sendSyncRequest(url, method, data, headers) {
|
|
|
|
- const xhr = new XMLHttpRequest();
|
|
|
|
- xhr.open(method, url, false);
|
|
|
|
|
|
+const random = {
|
|
|
|
+ /**
|
|
|
|
+ * 获取随机数
|
|
|
|
+ * @param min
|
|
|
|
+ * @param max
|
|
|
|
+ * @returns {number}
|
|
|
|
+ */
|
|
|
|
+ getInt: function (min, max) {
|
|
|
|
+ min = Math.ceil(min);
|
|
|
|
+ max = Math.floor(max);
|
|
|
|
+ return Math.floor(Math.random() * (max - min) + min); //The maximum is exclusive and the minimum is inclusive
|
|
|
|
+ },
|
|
|
|
+ /**
|
|
|
|
+ * 获取随机的一个值
|
|
|
|
+ * @param arr
|
|
|
|
+ * @returns {*}
|
|
|
|
+ */
|
|
|
|
+ getOneFromArray: function (arr) {
|
|
|
|
+ return arr[this.getInt(0, arr.length)];
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
|
|
- if (headers) {
|
|
|
|
- for (const key in headers) {
|
|
|
|
- xhr.setRequestHeader(key, headers[key]);
|
|
|
|
|
|
+
|
|
|
|
+/**
|
|
|
|
+ * 创建一个<eleName k="attrs[k]">text</eleName>样式的页面元素
|
|
|
|
+ * @param eleName
|
|
|
|
+ * @param text
|
|
|
|
+ * @param attrs
|
|
|
|
+ * @returns {*}
|
|
|
|
+ */
|
|
|
|
+function createEle(eleName, text, attrs) {
|
|
|
|
+ let ele = document.createElement(eleName);
|
|
|
|
+ // innerText 也就是 <p>text会被添加到这里</p>
|
|
|
|
+ ele.innerText = text;
|
|
|
|
+ // attrs 的类型是一个 map
|
|
|
|
+ for (let k in attrs) {
|
|
|
|
+ // 遍历 attrs, 给节点 ele 添加我们想要的属性
|
|
|
|
+ ele.setAttribute(k, attrs[k]);
|
|
|
|
+ }
|
|
|
|
+ // 返回节点
|
|
|
|
+ return ele;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/**
|
|
|
|
+ * 复制html内容到剪贴板
|
|
|
|
+ * @param inner_html
|
|
|
|
+ */
|
|
|
|
+function myCopy(inner_html) {
|
|
|
|
+ let tmpId = "tmpId123123" + getRandomInt(1, 10000);
|
|
|
|
+ let a = document.createElement('div');
|
|
|
|
+ a.id = tmpId;
|
|
|
|
+ a.innerHTML = inner_html
|
|
|
|
+ document.querySelector('body').appendChild(a)
|
|
|
|
+ let range = document.createRange();
|
|
|
|
+ range.selectNode(document.querySelector("#" + tmpId));
|
|
|
|
+ // 清除选择
|
|
|
|
+ window.getSelection().removeAllRanges();
|
|
|
|
+ window.getSelection().addRange(range);
|
|
|
|
+ console.log('复制成功');
|
|
|
|
+ document.execCommand('copy');
|
|
|
|
+ // 清除选择
|
|
|
|
+ window.getSelection().removeAllRanges();
|
|
|
|
+ document.querySelector("#" + tmpId).remove();
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+/**
|
|
|
|
+ * 自动关闭提示框
|
|
|
|
+ * @param str 提示文本
|
|
|
|
+ * @param sec 时间(秒)
|
|
|
|
+ */
|
|
|
|
+function showMsg(str, sec) {
|
|
|
|
+ const borderColor = "#336699"; //提示窗口的边框颜色
|
|
|
|
+ const sWidth = document.body.offsetWidth;
|
|
|
|
+ const sHeight = document.body.offsetHeight;
|
|
|
|
+ //背景div
|
|
|
|
+ const bgObj = document.createElement("div");
|
|
|
|
+ let alertBgDiv = 'alertBgDiv';
|
|
|
|
+ bgObj.setAttribute('id', alertBgDiv);
|
|
|
|
+ bgObj.style.cssText = `position: fixed; top: 0; background: #E8E8E8; filter: progid:DXImageTransform.Microsoft.Alpha(style=3,opacity=25,finishOpacity=75; opacity: 0.6; left: 0; width: ${sWidth}px; height: ${sHeight}px; z-index: 10000`;
|
|
|
|
+ document.body.appendChild(bgObj);
|
|
|
|
+ //创建提示窗口的div
|
|
|
|
+ const msgObj = document.createElement("div");
|
|
|
|
+ let alertMsgDiv = "alertMsgDiv";
|
|
|
|
+ msgObj.setAttribute("id", alertMsgDiv);
|
|
|
|
+ msgObj.setAttribute("align", "center");
|
|
|
|
+ msgObj.style.cssText = `background: white; border: 1px solid ${borderColor}; position: fixed; left: 50%; font: 15px/1.6em Verdana, Geneva, Arial, Helvetica, sans-serif; margin-left: -225px; top: ${document.body.scrollTop + (window.screen.availHeight / 2) - 150}px; text-align: center; line-height: 25px; z-index: 10001; min-width: 300px`;
|
|
|
|
+ document.body.appendChild(msgObj);
|
|
|
|
+ //提示信息标题
|
|
|
|
+ const title = document.createElement("h4");
|
|
|
|
+ let alertMsgTitle = "alertMsgTitle";
|
|
|
|
+ title.setAttribute("id", alertMsgTitle);
|
|
|
|
+ title.setAttribute("align", "left");
|
|
|
|
+ title.style.cssText = `margin:0; padding:3px; background:${borderColor}; filter:progid:DXImageTransform.Microsoft.Alpha(startX=20, startY=20, finishX=100, finishY=100,style=1,opacity=75,finishOpacity=100); opacity:0.75; border:1px solid ${borderColor}; font:12px Verdana, Geneva, Arial, Helvetica, sans-serif; color:white`;
|
|
|
|
+ title.innerHTML = "提示信息";
|
|
|
|
+ document.getElementById(alertMsgDiv).appendChild(title);
|
|
|
|
+ //提示信息
|
|
|
|
+ const txt = document.createElement("p");
|
|
|
|
+ txt.setAttribute("id", "msgTxt");
|
|
|
|
+ txt.style.margin = "16px 0";
|
|
|
|
+ txt.innerHTML = str;
|
|
|
|
+ document.getElementById(alertMsgDiv).appendChild(txt);
|
|
|
|
+
|
|
|
|
+ //设置关闭时间
|
|
|
|
+ window.setTimeout(() => {
|
|
|
|
+ document.body.removeChild(document.getElementById(alertBgDiv));
|
|
|
|
+ document.getElementById(alertMsgDiv).removeChild(document.getElementById(alertMsgTitle));
|
|
|
|
+ document.body.removeChild(document.getElementById(alertMsgDiv));
|
|
|
|
+ }, sec * 1000);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+/**
|
|
|
|
+ * 打印信息
|
|
|
|
+ * @param obj
|
|
|
|
+ */
|
|
|
|
+function log(obj) {
|
|
|
|
+ console.table(JSON.parse(JSON.stringify(obj)));
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+// 添加静态资源
|
|
|
|
+const staticLoader = {
|
|
|
|
+ /**
|
|
|
|
+ * 添加js引用 : addRemoteJs("https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.min.js");
|
|
|
|
+ */
|
|
|
|
+ addRemoteJs: function (jsUrl) {
|
|
|
|
+ if (document.querySelector(`script[src="${jsUrl}"]`)) {
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ const script = document.createElement('script');
|
|
|
|
+ script.src = jsUrl;
|
|
|
|
+ script.type = 'text/javascript';
|
|
|
|
+ document.head.appendChild(script);
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ addRemoteCss: function (cssUrl) {
|
|
|
|
+ if (document.querySelector(`link[href="${cssUrl}"]`)) {
|
|
|
|
+ return;
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+ const link = document.createElement('link');
|
|
|
|
+ link.href = cssUrl;
|
|
|
|
+ link.rel = 'stylesheet';
|
|
|
|
+ link.type = 'text/css';
|
|
|
|
+ document.head.appendChild(link);
|
|
|
|
+ },
|
|
|
|
+ /**
|
|
|
|
+ * 添加 Jq
|
|
|
|
+ */
|
|
|
|
+ addJq: function () {
|
|
|
|
+ const jqUrl = 'https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.min.js';
|
|
|
|
+ this.addRemoteJs(jqUrl);
|
|
}
|
|
}
|
|
|
|
|
|
- if (method.match(/^(POST|PUT)$/i)) {
|
|
|
|
- xhr.setRequestHeader('Content-Type', 'application/json');
|
|
|
|
- xhr.send(JSON.stringify(data));
|
|
|
|
- } else {
|
|
|
|
- xhr.send();
|
|
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+// 复制文本工具类
|
|
|
|
+const copyUtil = {
|
|
|
|
+ /**
|
|
|
|
+ * 复制,支持复制html: copyHtml('#wish_search_list .wish_s_item');
|
|
|
|
+ * @param css_selector
|
|
|
|
+ * @returns {Promise<void>}
|
|
|
|
+ */
|
|
|
|
+ copyFromSelector: async function (css_selector) {
|
|
|
|
+ const el = document.querySelector(css_selector);
|
|
|
|
+ const html = el.outerHTML;
|
|
|
|
+ await this.copyFromHtml(html);
|
|
|
|
+ },
|
|
|
|
+ copyFromHtml: async function (html) {
|
|
|
|
+ try {
|
|
|
|
+ await navigator.clipboard.write([
|
|
|
|
+ new ClipboardItem({
|
|
|
|
+ 'text/html': new Blob([html], {type: 'text/html'})
|
|
|
|
+ })
|
|
|
|
+ ]);
|
|
|
|
+ alert('复制成功');
|
|
|
|
+ } catch (err) {
|
|
|
|
+ console.error('复制失败', err);
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
|
|
- return JSON.parse(xhr.responseText);
|
|
|
|
|
|
+/**
|
|
|
|
+ * 在指定dom里面 添加 a 超链接 addLink(".media-title", " 转到豆瓣", `https://search.douban.com/movie/subject_search`);
|
|
|
|
+ * @param domSelector
|
|
|
|
+ * @param link_str
|
|
|
|
+ * @param linkUrl
|
|
|
|
+ */
|
|
|
|
+function addLink(domSelector, link_str, linkUrl) {
|
|
|
|
+ const eleScript = document.createElement("a");
|
|
|
|
+ eleScript.innerHTML = link_str.replaceAll(" ", " ");
|
|
|
|
+ eleScript.href = linkUrl;
|
|
|
|
+ document.querySelector(domSelector).appendChild(eleScript);
|
|
}
|
|
}
|