您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
一个好用的工具类
当前为
此脚本不应直接安装,它是供其他脚本使用的外部库。如果您需要使用该库,请在脚本元属性加入:// @require https://update.gf.qytechs.cn/scripts/455186/1121661/WhiteSevsUtils.js
/* * @overview 自己常用的工具类定义 * @copyright GPL-3.0-only * @author WhiteSevs * @version 0.1 */ let Utils = {}; /* * @param {string|function} func - 需要捕获错误的函数或函数格式的字符串 * @param {object} params - 该函数的参数和捕获到错误的函数的参数,类型为数组Array * @param {string|function} errorFunc - 捕获到错误后执行的函数或函数格式的字符串 * @example Utils.tryCatch("(pam)=>{console.log('this is a function and params is' + pam[0])}",["参数1"],"()=>{console.log('对错误进行处理判断')}"); */ Utils.tryCatch = (func, params, errorFunc) => { /* 捕获错误 */ if(func == null){ throw "警告: 参数 func 为不存在" } if (typeof func !== "function" && typeof func !== "string" ) { throw "参数 func 类型必须为function类型或者string类型" } if (params != null && typeof params !== "object" && typeof params !== "string") { throw "参数 params 类型必须为object类型或者string类型" } if (errorFunc != null && typeof errorFunc !== "object" && typeof errorFunc !== "string") { throw "参数 errorFunc 类型必须为function类型或者string类型" } var result = null; try { result = typeof func === "string" ? window.eval(func) : func(params); } catch (error) { console.log("%c" + (func.name ? func.name : func + "出现错误"), "color: #f20000"); console.log("%c" + ("错误原因:" + error), "color: #f20000"); console.trace(func); result = typeof func === "string" ? window.eval(errorFunc) : errorFunc(params); } finally { return result; } }; /* * @description 格式化时间字符串 * @param {string} str - 字符串格式的时间,例如:2022-11-21 00:00:00,或者是 00:00:00 * @return {number} - 返回时间戳 * @example Utils.formatTextToTimeStamp("2022-11-21 00:00:00"); */ Utils.formatTextToTimeStamp = (text) => { /* 把字符串格式的时间(完整,包括日期和时间)格式化成时间戳 */ if (typeof text !== 'string') { throw "参数 text 必须为string类型"; }; if (text.length === 8) { /* 参数只有时间 */ var today = new Date(); text = today.getFullYear() + "-" + (today.getMonth() + 1) + "-" + today.getDate() + " " + text; }; text = text.substring(0, 19); text = text.replace(/-/g, '/'); var timestamp = new Date(text).getTime(); return timestamp; }; /* * @description 定位网页中字符串位置并标亮,注意,该字符串必须是能在网页中看得到的,隐藏的是无法定位的 * @param {string} str - 需要寻找的字符串 * @param {boolean} caseSensitive - 区分大小写 * @return {boolean} true/false - 找到为true,否则false * @example Utils.findWindowPageString("xxxxx"); * @exampleResult true */ Utils.findWindowPageString = (str,caseSensitive=false) => { var TRange = null; var strFound; if (window.find) { // CODE FOR BROWSERS THAT SUPPORT window.find strFound = self.find(str,caseSensitive,true,true,false); if (strFound && self.getSelection && !self.getSelection().anchorNode) { strFound = self.find(str,caseSensitive,true,true,false) } if (!strFound) { strFound = self.find(str, 0, 1) while (self.find(str, 0, 1)) continue } } else if (navigator.appName.indexOf("Microsoft") != -1) { // EXPLORER-SPECIFIC CODE if (TRange != null) { TRange.collapse(false) strFound = TRange.findText(str) if (strFound) TRange.select() } if (TRange == null || strFound == 0) { TRange = self.document.body.createTextRange() strFound = TRange.findText(str) if (strFound) TRange.select() } } else if (navigator.appName == "Opera") { alert("Opera browsers not supported, sorry...") return; }; return strFound ? true:false; } /* * @description 格式化byte为KB、MB、GB、TB、PB、EB、ZB、YB、BB、NB、DB * @param {number} bitSize - 字节 * @param {boolean} addType - 是否添加单位,默认添加 * @return {string|number} - 添加单位就是字符串,否则为float类型,保留两位 * @example Utils.formatByteToSize("812304"); * @exampleResult */ Utils.formatByteToSize = (byteSize, addType = true) => { // B字节转KB、MB、GB byteSize = parseInt(byteSize); if (isNaN(byteSize)) { throw "参数 byteSize 格式不正确"; } var result = 0; var resultType = "KB"; var sizeData = {}; sizeData.KB = 1024; sizeData.MB = sizeData.KB * sizeData.KB; sizeData.GB = sizeData.MB * sizeData.KB; sizeData.TB = sizeData.GB * sizeData.KB; sizeData.PB = sizeData.TB * sizeData.KB; sizeData.EB = sizeData.PB * sizeData.KB; sizeData.ZB = sizeData.EB * sizeData.KB; sizeData.YB = sizeData.ZB * sizeData.KB; sizeData.BB = sizeData.YB * sizeData.KB; sizeData.NB = sizeData.BB * sizeData.KB; sizeData.DB = sizeData.NB * sizeData.KB; for (key in sizeData) { result = byteSize / sizeData[key]; resultType = key; if (sizeData.KB >= result) { break; } }; result = result.toFixed(2); result = addType ? result + resultType.toString() : parseFloat(result); return result; } /* * @description 数组按照内部某个值的大小比对排序,如[{"time":"2022-1-1"},{"time":"2022-2-2"}] * @param {string} propertyName - 数组内部项的某个属性的名称 * @param {boolean} sortByDesc - 排序方式为倒序,值为true或false,默认为true * @return {object} - 返回比较排序完成的数组 * @example [{"time":"2022-1-1"},{"time":"2022-2-2"}].sort(Utils.sortListByProperty("time")) * @example [{"time":"2022-1-1"},{"time":"2022-2-2"}].sort(Utils.sortListByProperty("time",false)) */ Utils.sortListByProperty = (propertyName, sortByDesc = true) => { if (typeof sortByDesc !== 'boolean') { throw "参数 sortByDesc 必须为boolean类型"; }; return function (after_obj, before_obj) { var beforeValue = before_obj[propertyName]; /* 前 */ var aferValue = after_obj[propertyName]; /* 后 */ if (sortByDesc) { if (aferValue > beforeValue) { return -1 } else if (aferValue < beforeValue) { return 1 } else { return 0 } } else { if (aferValue < beforeValue) { return -1 } else if (aferValue > beforeValue) { return 1 } else { return 0 } } } }; /* * @description Array添加一个内部属性,数组根据相同的字段合并成字符串 * @example [{"name":"Array内部方法: "},{"name":"mergeToString"}].mergeToString("name"); */ Utils.mergeArrayToString = (list,propertyName) => { if(list == null){ throw "参数 list 不能为空"; } if (propertyName == null) { throw "参数 propertyName 不能为null"; } var content = ""; Array.from(list).forEach((item) => { content = content + item[propertyName]; }) return content; }; /* * @description JSON内所有的值转为Array数组 * @param {object} _json_ - JSON数据 * @return {object} - 返回数组 * @example Utils.jsonAllValueToArray({"Utils":"jsonToArray","return","Array"}); * @exampleResult ['jsonToArray', 'Array'] */ Utils.jsonAllValueToArray = (_json_) => { if (typeof _json_ !== 'object') { throw "参数 _json_ 必须为object类型" } var retArray = []; Object.keys(_json_).forEach(function (key) { retArray = retArray.concat(_json_[key]); }) return retArray; }; /* * @description JSON格式的字符串转为JSON对象 * @param {string} text - JSON格式的字符串 * @return {object} - 返回JSON对象 * @example Utils.jsonStrToObject('{"Utils":"jsonStrToObject","return","json"}'); * @exampleResult {"Utils":"jsonStrToObject","return","json"} */ Utils.jsonStrToObject = (text) => { if (typeof text !== 'string') { throw "参数 text 类型必须为string类型" } return window.eval("(" + text + ")"); }; /* * @description 获取数组的随机值 * @param {string} array - 数组数据 * @return {string} - 返回数组的随机值 * @example Utils.getArrayRandValue(["Utils","getArrayRandValue"]); * @exampleResult getArrayRandValue */ Utils.getArrayRandValue = (_array_) => { return _array_[Math.floor(Math.random() * _array_.length)]; }; /* * @description 获取两个数字区间的随机值 * @param {number} number - 数字区间 * @param {number} number2 - 数字区间 * @return {number} - 返回两个数字区间的随机值 * @example Utils.getRandNumber(1,10); * @exampleResult 5 * @example Utils.getRandNumber(10,1); * @exampleResult 8 */ Utils.getRandNumber = (number, number2) => { if (typeof number !== "number") { throw "参数 number 必须为number类型"; } if (typeof number2 !== "number") { throw "参数 number2 必须为number类型"; } var leftNumber = number > number2 ? number2 : number; var rightNumber = number > number2 ? number : number2; return Math.round(Math.random() * (rightNumber - leftNumber)) + leftNumber; }; /* * @description 获取格式化后的Date类型时间 * @param {string} text - 需要格式化的字符串或者时间戳 * @param {string} types - 格式化成的显示类型 * yyyy 年 * MM 月 * dd 天 * HH 时 (24小时制) * hh 时 (12小时制) * mm 分 * ss 秒 * @return {string} - 返回格式化后的时间 * @example Utils.getFormatTime("HH:mm:ss","2022-08-21 23:59:00"); * @exampleResult 23:59:00 * @example Utils.getFormatTime("HH:mm:ss",1669187424988); * @exampleResult 15:10:13 */ Utils.getFormatTime = (types = "yyyy-MM-dd HH:mm:ss", text) => { if( typeof types !== "string"){ throw "参数 types 必须是string类型"; } if(text != null && (typeof text !== "string" && typeof text !== "number") ){ throw "参数 text 必须是string类型或者number类型"; } var time = text == null ? new Date(): new Date(text); function _checkTime_(i) { /* 校验时间补0 */ if (i < 10) return "0" + i; return i; } function _timeSystemChange_(_hour_) { /* 时间制修改 24小时制转12小时制 */ return _hour_ > 12 ? _hour_ - 12 : _hour_; }; var timeRegexp = { "yyyy": time.getFullYear(), /* 年 */ "MM": _checkTime_(time.getMonth() + 1), /* 月 */ "dd": _checkTime_(time.getDate()), /* 日 */ "HH": _checkTime_(time.getHours()), /* 时 (24小时制) */ "hh": _checkTime_(_timeSystemChange_(time.getHours())), /* 时 (12小时制) */ "mm": _checkTime_(time.getMinutes()), /* 分 */ "ss": _checkTime_(time.getSeconds()), /* 秒 */ }; Object.keys(timeRegexp).forEach(function (key) { var replaecRegexp = new RegExp(key, "g"); types = types.replace(replaecRegexp, timeRegexp[key]); }); return types; }, /* * @description 【手机】检测点击的地方是否在该元素区域内 * @param {object} obj - 需要检测的DOM元素 * @return {boolean} - 返回true或false * @example Utils.checkClickInDOM(document.querySelector(".xxx")); * @exampleResult false */ Utils.checkClickInDOM = (obj) => { if (typeof obj !== "object") { throw "参数 obj 类型必须为object类型"; } var x = Number(window.event.clientX) /* 鼠标相对屏幕横坐标 */ var y = Number(window.event.clientY) /* 鼠标相对屏幕纵坐标 */ var obj_x_left = Number(obj.getBoundingClientRect().left) /* obj相对屏幕的横坐标 */ var obj_x_right = Number( obj.getBoundingClientRect().left + obj.clientWidth ) /* obj相对屏幕的横坐标+width */ var obj_y_bottom = Number( obj.getBoundingClientRect().top + obj.clientHeight ) /* obj相对屏幕的纵坐标+height */ var obj_y_top = Number(obj.getBoundingClientRect().top) /* obj相对屏幕的纵坐标 */ if ((x >= obj_x_left && x <= obj_x_right && y >= obj_y_top && y <= obj_y_bottom) || obj.outerHTML.indexOf(window.event.target.innerHTML) != -1) { return true } else { return false } }; /* * @description 同步执行延时函数 * @param {object|string} fnStr - 需要延时的函数或字符串格式的函数 * @param {number} delayTime - 需要检测的DOM元素 * @return {All|无返回值} - 返回自定义类型数据或者无返回 * @example await Utils.asyncSetTimeOut(xxxFunction, 2500); * @exampleResult xxx * @example await Utils.asyncSetTimeOut("()=>{console.log(12345)}", 2500); * @exampleResult 无返回值 */ Utils.asyncSetTimeOut = (fnStr, delayTime) => { if (typeof fnStr !== "function" && typeof fnStr !== "string") { throw "参数 fnStr 类型必须为function类型或者string类型" }; if (typeof delayTime !== "number") { throw "参数 delayTime 类型必须为number类型" }; return new Promise(res => { setTimeout(() => { res(Utils.tryCatch(fnStr)); }, delayTime); }) }; /* * @description 同步执行foreach函数,遍历数组 * @param {object} arrayData - 需要遍历的数组 * @param {function} handleDataFunction - 对该数组进行操作的函数,该函数的参数为数组格式的参数,[数组下标,数组项] * @return 无返回值 * @example await Utils.asyncArrayForEach([1,2,3],xxxFunction); */ Utils.asyncArrayForEach = (arrayData, handleDataFunction) => { if (typeof arrayData !== "object") { throw "参数 arrayData 类型必须为object类型" } if (typeof handleDataFunction !== "object" && typeof handleDataFunction !== "string") { throw "参数 handleDataFunction 类型必须为object或者string类型" } return Promise.all( Array.from(arrayData).map(async (item, index) => { await Utils.tryCatch(handleDataFunction, [index, item]); }) ); }; /* * @description 同步延迟xxx毫秒 * @param {number} delayTime - 需要遍历的数组 * @return {无返回值} * @example await Utils.sleep(2500); - 同步延时2500毫秒 */ Utils.sleep = (delayTime) => { if (typeof delayTime !== "number") { throw "参数 delayTime 类型必须为number类型" } return new Promise(res => { setTimeout(() => { res(); }, delayTime); }) }; /* * @description 注册(不可用)全局函数Cookies * @function Cookies.get("key") * @param {string|number} key - 需要获取的cookie的key * @return {string} 获取到的cookie值或者为空 * @function Cookies.set("key","value",8400); * @param {string|number} key - 需要设置的cookie的key * @param {All} key - 需要设置的cookie的value * @param {number} time - 需要设置的cookie的过期时间 * @return 无返回值 * @example Utils.registerWindowCookies(); * Cookies.get("xxxx"); */ Utils.registerWindowCookies = () => { /*! js-cookie v3.0.1 | MIT */ (function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : typeof define === 'function' && define.amd ? define(factory) : (global = global || self, (function () { var current = global.Cookies; var exports = global.Cookies = factory(); exports.noConflict = function () { global.Cookies = current; return exports; }; }())); }(this, (function () { 'use strict'; /* eslint-disable no-var */ function assign(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { target[key] = source[key]; } } return target } /* eslint-enable no-var */ /* eslint-disable no-var */ var defaultConverter = { read: function (value) { if (value[0] === '"') { value = value.slice(1, -1); } return value.replace(/(%[\dA-F]{2})+/gi, decodeURIComponent) }, write: function (value) { return encodeURIComponent(value).replace( /%(2[346BF]|3[AC-F]|40|5[BDE]|60|7[BCD])/g, decodeURIComponent ) } }; /* eslint-enable no-var */ /* eslint-disable no-var */ function init(converter, defaultAttributes) { function set(key, value, attributes) { if (typeof document === 'undefined') { return } attributes = assign({}, defaultAttributes, attributes); if (typeof attributes.expires === 'number') { attributes.expires = new Date(Date.now() + attributes.expires * 864e5); } if (attributes.expires) { attributes.expires = attributes.expires.toUTCString(); } key = encodeURIComponent(key) .replace(/%(2[346B]|5E|60|7C)/g, decodeURIComponent) .replace(/[()]/g, escape); var stringifiedAttributes = ''; for (var attributeName in attributes) { if (!attributes[attributeName]) { continue } stringifiedAttributes += '; ' + attributeName; if (attributes[attributeName] === true) { continue } /* Considers RFC 6265 section 5.2: ... 3. If the remaining unparsed-attributes contains a %x3B (";") character: Consume the characters of the unparsed-attributes up to, not including, the first %x3B (";") character. ... */ stringifiedAttributes += '=' + attributes[attributeName].split(';')[0]; } return (document.cookie = key + '=' + converter.write(value, key) + stringifiedAttributes) } function get(key) { if (typeof document === 'undefined' || (arguments.length && !key)) { return } /* To prevent the for loop in the first place assign an empty array in case there are no cookies at all. */ var cookies = document.cookie ? document.cookie.split('; ') : []; var jar = {}; for (var i = 0; i < cookies.length; i++) { var parts = cookies[i].split('='); var value = parts.slice(1).join('='); try { var foundKey = decodeURIComponent(parts[0]); jar[foundKey] = converter.read(value, foundKey); if (key === foundKey) { break } } catch (e) {} } return key ? jar[key] : jar } return Object.create({ set: set, get: get, remove: function (key, attributes) { set( key, '', assign({}, attributes, { expires: -1 }) ); }, withAttributes: function (attributes) { return init(this.converter, assign({}, this.attributes, attributes)) }, withConverter: function (converter) { return init(assign({}, this.converter, converter), this.attributes) } }, { attributes: { value: Object.freeze(defaultAttributes) }, converter: { value: Object.freeze(converter) } }) } var api = init(defaultConverter, { path: '/' }); /* eslint-enable no-var */ return api; }))) }, /* * @description base64转blob * @param {string} dataurl - base64的数据 * @return {string} blob的链接 * @example Utils.base64ToBlob("data:image/jpeg;base64,....."); * @exampleResult blob://xxxxxxx */ Utils.base64ToBlob = (dataurl) => { if (typeof dataurl !== "string") { throw "参数 dataurl 类型必须为string类型"; } var arr = dataurl.split(','), mime = arr[0].match(/:(.*?);/)[1], bstr = atob(arr[1]), n = bstr.length, u8arr = new Uint8Array(n); while (n--) { u8arr[n] = bstr.charCodeAt(n); } return new Blob([u8arr], { type: mime }); }, /* * @description base64转File对象 * @param {string} dataurl - base64的数据 * @return {string} blob的链接 * @example Utils.base64ToFile("data:image/jpeg;base64,....."); * @exampleResult object */ Utils.base64ToFile = (dataurl, fileName) => { if (typeof dataurl !== "string") { throw "参数 dataurl 类型必须为string类型"; } if (typeof fileName !== "string") { throw "参数 fileName 类型必须为string类型"; } var arr = dataurl.split(','), mime = arr[0].match(/:(.*?);/)[1], bstr = atob(arr[1]), n = bstr.length, u8arr = new Uint8Array(n); while (n--) { u8arr[n] = bstr.charCodeAt(n); } return new File([u8arr], fileName, { type: mime }); }; /* * @description blob转File对象 * @param {string} theBlob - 需要转换的blob的链接 * @param {string} fileName - 转换成的File对象的文件名称 * @return {object} File对象 * @example Utils.blobToFile("blob://xxxxx"); * @exampleResult object */ Utils.blobToFile = (theBlob, fileName) => { if (typeof theBlob !== "string") { throw "参数 theBlob 类型必须为string类型"; } if (typeof fileName !== "string") { throw "参数 fileName 类型必须为string类型"; } theBlob.lastModifiedDate = new Date(); theBlob.name = fileName; return theBlob; }, /* * @description 同步File对象转base64 * @param {object} file - 需要转换的File对象 * @return {string} base64格式的数据 * @example await Utils.asyncFileToBase64(object); * @exampleResult data:image/jpeg:base64/,xxxxxx */ Utils.asyncFileToBase64 = (file) => { var reader = new FileReader(); reader.readAsDataURL(file); return new Promise(res => { reader.onload = function (e) { res(e.target.result); } }) }; /* * @description 下载base64格式的数据 * @param {string} base64Content - 需要转换的base64数据 * @param {string} fileName - 需要保存的文件名 * @example Utils.downloadBase64("data:image/jpeg:base64/,xxxxxx"); */ Utils.downloadBase64 = (base64Content, fileName) => { var aLink = document.createElement('a'); var blob = Utils.base64ToBlob(base64Content); var evt = document.createEvent('HTMLEvents'); evt.initEvent('click', true, true) // initEvent 不加后两个参数在FF下会报错 事件类型,是否冒泡,是否阻止浏览器的默认行为 aLink.download = fileName; aLink.href = URL.createObjectURL(blob); aLink.click(); }; /* * @description 判断是否是手机访问 * @return {boolean} - 返回如果是手机true,否则false * @example Utils.isPhone(); * @exampleResult true */ Utils.isPhone = () => { return Boolean(/(iPhone|iPad|iPod|iOS|Android)/i.test(navigator.userAgent)); }; /* * @description 自定义字典,用于new * @example new let dictionary = Utils.Dictionary(); * @example dictionary.set("xxx","xxx"); * @example dictionary.get("xxx"); * @example dictionary.has("xxx"); */ Utils.Dictionary = function () { this.items = {}; //检查是否有某一个键 this.has = function (key) { return this.items.hasOwnProperty(key); } //为字典添加某一个值 this.set = function (key, val) { this.items[key] = val; } //删除某一个键 this.delete = function (key) { if (this.has(key)) { delete this.items[key]; return true; } return false; } //查找某一特定项 this.get = function (key) { return this.has(key) ? this.items[key] : undefined; } //返回字典中的所有值 this.values = function () { var res = []; for (var prop in this.items) { if (this.has(prop)) { res.push(this.items[prop]); } } return res; } //清空字典 this.clear = function () { this.items = {}; } //获取字典的长度 this.size = function () { return Object.keys(this.items).length; } //获取字典所有的键 this.keys = function () { return Object.keys(this.items); } //返回字典本身 this.getItems = function () { return this.items; } }; /* * @description JSON数据从源端替换到目标端中,如果目标端存在该数据则替换,不添加,返回结果为目标端替换完毕的结果 * @param {object} target - 目标端 * @param {object} source - 源端 * @example Utils.assignJSON({"1":1,"2":{"3":3}}); * @exampleResult */ Utils.assignJSON = (target,source) => { for (var target_key in target) { if (typeof source[target_key] !== "undefined") { if(typeof source[target_key] === "object"){ target[target_key] = Utils.assignJSON(target[target_key],source[target_key]); }else{ target[target_key] = source[target_key]; } } }; return target; };
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址