util.js 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361
  1. // 引用 https://web.tianyunperfect.cn/simple/js/util.js
  2. function lt(obj) {
  3. console.table(JSON.parse(JSON.stringify(obj)));
  4. }
  5. /**
  6. * 深度克隆
  7. * @param obj
  8. * @returns {any}
  9. */
  10. function deepClone(obj) {
  11. return JSON.parse(JSON.stringify(obj))
  12. }
  13. // 日期工具类
  14. const dataUtil = {
  15. // 日期 -> 字符串:formatDate(date, 'yyyy-MM-dd hh:mm:ss');
  16. formatDate: function (date, format) {
  17. const pad = (n) => (n < 10 ? '0' + n : n);
  18. const replacements = {
  19. 'yyyy': date.getFullYear(),
  20. 'MM': pad(date.getMonth() + 1),
  21. 'dd': pad(date.getDate()),
  22. 'hh': pad(date.getHours()),
  23. 'mm': pad(date.getMinutes()),
  24. 'ss': pad(date.getSeconds()),
  25. 'qq': Math.floor((date.getMonth() + 3) / 3), //季度
  26. 'SSS': pad(date.getMilliseconds(), 3) //毫秒
  27. };
  28. let result = format;
  29. for (const key in replacements) {
  30. result = result.replace(key, replacements[key]);
  31. }
  32. return result;
  33. },
  34. // 日期字符串 -> 日期: parseDate("2022-10-30 16:13:49")
  35. parseDate: function (dateString) {
  36. const date = new Date(Date.parse(dateString));
  37. return date;
  38. },
  39. // 当前日期
  40. getNowStr: function () {
  41. return this.formatDate(new Date(), 'yyyy-MM-dd hh:mm:ss');
  42. },
  43. }
  44. // 添加响应拦截器
  45. axios.interceptors.response.use(function (response) {
  46. // 对响应数据做点什么
  47. return response.data;
  48. }, function (error) {
  49. // 对响应错误做点什么
  50. return Promise.reject(error);
  51. });
  52. /**
  53. * 远程请求
  54. * @type {{async: (function(*, *, *, *): Promise<unknown>), xhr_send: request.xhr_send, sync: (function(*, *, *, *): any)}}
  55. */
  56. const requestUtil = {
  57. xhr_send(xhr, method, headers, data) {
  58. if (headers) {
  59. for (const key in headers) {
  60. xhr.setRequestHeader(key, headers[key]);
  61. }
  62. }
  63. if (method.match(/^(POST|PUT)$/i)) {
  64. if (!headers || !headers.hasOwnProperty("Content-Type")) {
  65. xhr.setRequestHeader("Content-Type", "application/json");
  66. }
  67. xhr.send(JSON.stringify(data));
  68. } else {
  69. xhr.send();
  70. }
  71. },
  72. /**
  73. * 异步请求:requestUtil.async('https://jsonplaceholder.typicode.com/posts/1', 'GET', null, null)
  74. * .then(data => console.log(data))
  75. * .catch(error => console.error(error));
  76. */
  77. async(url, method, data = {}, headers = {}) {
  78. return new Promise((resolve, reject) => {
  79. const xhr = new XMLHttpRequest();
  80. xhr.open(method, url, true);
  81. this.xhr_send(xhr, method, headers, data);
  82. xhr.onload = () => {
  83. resolve(JSON.parse(xhr.responseText));
  84. };
  85. xhr.onerror = () => reject(xhr.statusText);
  86. });
  87. },
  88. /**
  89. * 拼接 url
  90. */
  91. buildUrl(url, params) {
  92. const urlObj = new URL(url);
  93. // @ts-ignore
  94. for (const key in params) {
  95. urlObj.searchParams.set(key, params[key]);
  96. }
  97. return urlObj.toString();
  98. },
  99. /**
  100. * 同步请求 let a = request.sync("https://httpbin.tianyunperfect.cn/ip","GET",null,null)
  101. */
  102. sync(url, method, data = {}, headers = {}) {
  103. const xhr = new XMLHttpRequest();
  104. xhr.open(method, url, false);
  105. this.xhr_send(xhr, method, headers, data);
  106. return JSON.parse(xhr.responseText);
  107. },
  108. };
  109. /**
  110. * 休眠一段时间: await sleep(2000)
  111. * @param time
  112. * @returns {Promise<unknown>}
  113. */
  114. function sleep(time) {
  115. return new Promise((resolve) => setTimeout(resolve, time));
  116. }
  117. /**
  118. * 根据选择器 选择某一个dom,10秒钟内
  119. * @param sel
  120. * @returns {Promise<*>}
  121. */
  122. async function getDom(sel) {
  123. for (let i = 0; i < 100; i++) {
  124. let dom = document.querySelector(sel);
  125. if (dom) {
  126. return dom;
  127. } else {
  128. await sleep(100);
  129. }
  130. }
  131. }
  132. /**
  133. * 根据选择器 选择所有dom,10秒钟内
  134. * @param sel
  135. * @returns {Promise<*>}
  136. */
  137. async function getDomAll(sel) {
  138. for (let i = 0; i < 100; i++) {
  139. let dom = document.querySelectorAll(sel);
  140. if (dom.length > 0) {
  141. return dom;
  142. } else {
  143. await sleep(100);
  144. }
  145. }
  146. }
  147. /**
  148. * 添加全局样式: addGlobalStyle('.box {height: 100px !important;}');
  149. */
  150. function addGlobalStyle(newStyle) {
  151. let styleElement = document.getElementById('styles_js');
  152. if (!styleElement) {
  153. styleElement = document.createElement('style');
  154. styleElement.type = 'text/css';
  155. styleElement.id = 'styles_js';
  156. document.getElementsByTagName('head')[0].appendChild(styleElement);
  157. }
  158. styleElement.appendChild(document.createTextNode(newStyle));
  159. }
  160. /**
  161. * 获取 指定 name 的 url 参数
  162. * @param url
  163. * @param name
  164. * @returns {string|string}
  165. */
  166. function getQueryStringByUrl(url, name) {
  167. let reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)", "i");
  168. let r = url.substring(url.indexOf('?') + 1).match(reg); //获取url中"?"符后的字符串并正则匹配
  169. let context = "";
  170. if (r != null)
  171. context = r[2];
  172. reg = null;
  173. r = null;
  174. return context == null || context === "" || context === "undefined" ? "" : decodeURI(context);
  175. }
  176. /**
  177. * 获取 指定 name 的 url 参数
  178. * @param name
  179. * @returns {string}
  180. */
  181. function getQueryString(name) {
  182. return getQueryStringByUrl(location.href, name);
  183. }
  184. // 随机数
  185. const randomUtil = {
  186. /**
  187. * 获取随机数
  188. * @param min
  189. * @param max
  190. * @returns {number}
  191. */
  192. getInt: function (min, max) {
  193. min = Math.ceil(min);
  194. max = Math.floor(max);
  195. return Math.floor(Math.random() * (max - min) + min); //The maximum is exclusive and the minimum is inclusive
  196. },
  197. /**
  198. * 获取随机的一个值
  199. * @param arr
  200. * @returns {*}
  201. */
  202. getOneFromArray: function (arr) {
  203. return arr[this.getInt(0, arr.length)];
  204. }
  205. }
  206. /**
  207. * 创建一个<eleName k="attrs[k]">text</eleName>样式的页面元素
  208. * @param eleName
  209. * @param text
  210. * @param attrs
  211. * @returns {*}
  212. */
  213. function createEle(eleName, text, attrs) {
  214. let ele = document.createElement(eleName);
  215. // innerText 也就是 <p>text会被添加到这里</p>
  216. ele.innerText = text;
  217. // attrs 的类型是一个 map
  218. for (let k in attrs) {
  219. // 遍历 attrs, 给节点 ele 添加我们想要的属性
  220. ele.setAttribute(k, attrs[k]);
  221. }
  222. // 返回节点
  223. return ele;
  224. }
  225. /**
  226. * 自动关闭提示框
  227. * @param str 提示文本
  228. * @param sec 时间(秒)
  229. */
  230. function showMsg(str, sec) {
  231. const borderColor = "#336699"; //提示窗口的边框颜色
  232. const sWidth = document.body.offsetWidth;
  233. const sHeight = document.body.offsetHeight;
  234. //背景div
  235. const bgObj = document.createElement("div");
  236. let alertBgDiv = 'alertBgDiv';
  237. bgObj.setAttribute('id', alertBgDiv);
  238. 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`;
  239. document.body.appendChild(bgObj);
  240. //创建提示窗口的div
  241. const msgObj = document.createElement("div");
  242. let alertMsgDiv = "alertMsgDiv";
  243. msgObj.setAttribute("id", alertMsgDiv);
  244. msgObj.setAttribute("align", "center");
  245. 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`;
  246. document.body.appendChild(msgObj);
  247. //提示信息标题
  248. const title = document.createElement("h4");
  249. let alertMsgTitle = "alertMsgTitle";
  250. title.setAttribute("id", alertMsgTitle);
  251. title.setAttribute("align", "left");
  252. 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`;
  253. title.innerHTML = "提示信息";
  254. document.getElementById(alertMsgDiv).appendChild(title);
  255. //提示信息
  256. const txt = document.createElement("p");
  257. txt.setAttribute("id", "msgTxt");
  258. txt.style.margin = "16px 0";
  259. txt.innerHTML = str;
  260. document.getElementById(alertMsgDiv).appendChild(txt);
  261. //设置关闭时间
  262. window.setTimeout(() => {
  263. document.body.removeChild(document.getElementById(alertBgDiv));
  264. document.getElementById(alertMsgDiv).removeChild(document.getElementById(alertMsgTitle));
  265. document.body.removeChild(document.getElementById(alertMsgDiv));
  266. }, sec * 1000);
  267. }
  268. /**
  269. * 打印信息
  270. * @param obj
  271. */
  272. function log(obj) {
  273. console.table(JSON.parse(JSON.stringify(obj)));
  274. }
  275. // 添加静态资源
  276. const staticLoader = {
  277. /**
  278. * 添加js引用 : addRemoteJs("https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.min.js");
  279. */
  280. addRemoteJs: function (jsUrl) {
  281. if (document.querySelector(`script[src="${jsUrl}"]`)) {
  282. return;
  283. }
  284. const script = document.createElement('script');
  285. script.src = jsUrl;
  286. script.type = 'text/javascript';
  287. document.head.appendChild(script);
  288. },
  289. addRemoteCss: function (cssUrl) {
  290. if (document.querySelector(`link[href="${cssUrl}"]`)) {
  291. return;
  292. }
  293. const link = document.createElement('link');
  294. link.href = cssUrl;
  295. link.rel = 'stylesheet';
  296. link.type = 'text/css';
  297. document.head.appendChild(link);
  298. },
  299. /**
  300. * 添加 Jq
  301. */
  302. addJq: function () {
  303. const jqUrl = 'https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.min.js';
  304. this.addRemoteJs(jqUrl);
  305. }
  306. }
  307. // 复制文本工具类
  308. const copyUtil = {
  309. /**
  310. * 复制,支持复制html: copyHtml('#wish_search_list .wish_s_item');
  311. * @param css_selector
  312. * @returns {Promise<void>}
  313. */
  314. copyFromSelector: async function (css_selector) {
  315. const el = document.querySelector(css_selector);
  316. const html = el.outerHTML;
  317. await this.copyFromHtml(html);
  318. },
  319. copyFromHtml: async function (html) {
  320. try {
  321. await navigator.clipboard.write([
  322. new ClipboardItem({
  323. 'text/html': new Blob([html], {type: 'text/html'})
  324. })
  325. ]);
  326. console.log('复制成功');
  327. } catch (err) {
  328. console.error('复制失败', err);
  329. }
  330. }
  331. }