您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
挂载到window下一级属性集合-常用工具函数
当前为
// ==UserScript== // @name 工具函数tls // @namespace http://tampermonkey.net/ // @version 0.1.5 // @description 挂载到window下一级属性集合-常用工具函数 // @author Enjoy_li // @match *://*/* // @homepage https://greasyfork.org/zh-CN/scripts/468302-%E5%B7%A5%E5%85%B7%E5%87%BD%E6%95%B0tls // @license MIT // @icon https://foruda.gitee.com/avatar/1671100286067517749/4867929_enjoy_li_1671100285.png!avatar60 // @grant none // ==/UserScript== ; (function (win) { getLogObjectValue(['v$0','vtemp1']) const tools = { backPrototype, createPlainFile, getRegMobile, phoneFormat, getRegName, getRegEmail, getRegIDCard, getQuery, toSearch, transformThousandth, deleteProperty, asyncRequire, transformData, previewFile, dateUtil, toWithOpener, downloadFile, base64ToBlob, base64ImgtoFile, isHasBtnPower, getBrowerEnv, formatReportDataToStr, copyStrToClipboard, getPropertiesOfObj, lgd, lgd0, lgdt1, getPrototypeChainOfObject, getLogObjectValue } function getPrototypeChainOfObject(Obj) { /** @描述 对象原型链 */ let idx = 0 let str = `${Obj.name || '参数'}的原型链是: ` next(Obj) return str /** @描述 递归 */ function next(obj) { let ObjType = Object.toLocaleString.call(obj) let ObjFlag = ObjType.match(/^\[object ([a-zA-Z]+)\]/)?.[1] || typeof ObjType str += `第 ${idx} 级【${ObjFlag}】.__proto__ ▶️ ` idx++ if (obj.__proto__) { next(obj.__proto__) } else { str += `第 ${idx} 级【null】` } } } function lgdt1(...rest) { /** @描述 以对象形式打印 $0 */ console.log(`temp1 ==%O`,temp1,...rest) } function lgd(...args) { /** @描述 以对象形式打印 temp1 */ let [desc,...rest] = args if (rest.length && typeof desc === 'string') { return console.log(`${desc} %O`,...rest) } console.log(`%O`,...args) } function lgd0(...rest) { /** @描述 以对象形式打印 $0 */ console.log(`$0 ==%O`,$0,...rest) } function backPrototype(resourceObj) { /** * @description 对象原型链:继承谁的属性和方法 * @param {*} resourceObj * @returns {*} string */ let str = '' next(resourceObj) str = str + 'null' console.log(`%c 该对象原型链是:`,'color:red',str) return str function next(obj) { let ObjType = Object.toLocaleString.call(obj) let ObjFlag = ObjType.match(/^\[object ([a-zA-Z]+)\]/)?.[1] || '无' str = str + ObjFlag + ' + .__proto__ >> ' if (obj.__proto__) { next(obj.__proto__) } } } function createPlainFile(content = { a: 'a' },name = 'name') { /** * @description 创建文本文件 * @param {string} [content={ a: 'a' }] * @param {string} [name='name'] */ // 下载保存json文件 var eleLink = document.createElement("a"); eleLink.download = name + '.json'; // 字符内容转变成blob地址 var data = JSON.stringify(content,undefined,4); var blob = new Blob([data],{ type: "text/json" }); eleLink.href = URL.createObjectURL(blob); // 触发点击 eleLink.click(); // 然后移除 } function getRegMobile() { /** @描述 正则 - 手机号 */ return /^1[2|3|4|5|6|7|8|9][\d]{9}$/ } function phoneFormat(phone = '') { /** @描述 格式化 - 手机号 */ if (!phone || !/^(?:(?:\+|00)86)?1[3-9]\d{9}$/.test(phone)) return; phone = phone.replace(/\D/g,'').slice(0,11); phone = phone .replace(/^(\d{3})/,'$1 ') .replace(/(\d{4})/,'$1 ') .replace(/[\s]+$/,'') return phone; } function getRegName() { /** @描述 正则 - 姓名 */ return /^[0-9|A-Za-z|\u4e00-\u9fa5|\s]+$/ } function getRegEmail() { /** @描述 正则 - 邮箱 */ return /^[_a-z0-9-]+(\.[_a-z0-9-]+)*@[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,4})$/i } function getRegIDCard() { /** @描述 正则 - 大陆身份证号码 */ return /^[1-9]\d{7}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}$|^[1-9]\d{5}[1-9]\d{3}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}([0-9]|X)$/ } function getQuery(search = window.location.search) { /** @描述 获取 url 参数 */ const query = {} search .substr(1) .split('&') .forEach((str) => { const strArr = str.split('=') const key = strArr[0] if (!key) return let val = decodeURIComponent(strArr[1]) try { val = JSON.parse(val) } catch (err) { } query[key] = val }) return query } function toSearch(obj = {}) { /** @描述 转换成 url search */ const arr = Object.keys(obj).map((key) => { let val = obj[key] if (typeof val !== 'string') { try { val = JSON.stringify(val) } catch (err) { console.error(err) } } return `${key}=${encodeURIComponent(val)}` }) return '?' + arr.join('&') } function transformThousandth(value,fixed) { /** * 格式化金额 千分符 * @param value * @param fixed */ const needFixed = fixed != null const num = Number(value) if (isNaN(num)) { return needFixed ? (0).toFixed(fixed) : '0' } // return (needFixed ? num.toFixed(fixed) : num.toString()).replace(/(\d{1,3})(?=(\d{3})+(?:$|\.))/g, '$1,') const str = needFixed ? num.toFixed(fixed) : num.toString() const arr = str.split('.') let result = arr[0] ? arr[0].replace(/(?=(?!\b)(\d{3})+$)/g,',') : '0' if (arr[1] != null) { result += `.${arr[1]}` } return result } function deleteProperty(obj = {},v = [undefined,null,'']) { /** * 删除指定值的属性 * @param obj */ const res = {} const isArray = Array.isArray(v) for (const key in obj) { if (isArray) { if (!v.includes(obj[key])) res[key] = obj[key] } else { if (obj[key] !== v) res[key] = obj[key] } } return res } function asyncRequire(url,name,type) { /** * 通过插入标签以加载 js/css 文件 * @param {String} url 需要载入的 js/css url * @param {String} name 文件载入后挂载到 window 下的变量名 * @param {String} type 文件类型 默认取后缀名 */ return new Promise((resolve,reject) => { const head = document.head || document.getElementsByTagName('head')[0] || document.body const filePath = url.split('?')[0] const ext = filePath.substring(filePath.lastIndexOf('.') + 1) if (document.getElementById(`async-require-${name || 'unknown'}`)) { return resolve(name ? window[name] : 'loaded') } let element if (ext == 'js' || type == 'js') { element = document.createElement('script') element.src = url element.onload = (e) => resolve(name ? window[name] : e) } else if (ext == 'css' || type == 'css') { element = document.createElement('link') element.rel = 'stylesheet' element.type = 'text/css' element.href = url element.onload = resolve } else { return console.warn('好像有点不对劲...请指定文件类型: js | css') } element.id = `async-require-${name}` element.onerror = reject head.appendChild(element) }) } function transformData(sourceData,relation) { /** * 返回数据 * @param {Array} sourceData 原数组 * @param {Array} 映射字段 */ return sourceData.map((item) => { const [key,name] = relation return { label: item[name], value: item[key], } }) } function previewFile(fileUrl) { /** * 在线预览文件 * @param {String} fileUrl 静态资源地址 */ let link = document.createElement('a') link.href = fileUrl let ext = (link.pathname.split('.')[1] || '').toLowerCase() const allowedExt = { bmp: 1, gif: 1, jpg: 1, jpeg: 1, png: 1, apng: 1, webp: 1, htm: 1, html: 1, pdf: 1, } if (ext && allowedExt[ext]) { const url = `https://static.hrwork.com/tools/pdfviewer/index.html?file=${encodeURIComponent( fileUrl )}` if (window?.__ZPA_CRX) { return void dispatchEvent(new CustomEvent('$create_tab',{ detail: url })) } window.open(url) } else { alert(`不支持在线预览此类型(${ext ?? ''})文件`) } } function dateUtil(time = new Date()) { /** * 获取特定格式日期 * date: 可以为日期字符串、日期对象,不传参数默认当前系统时间 * format: 输出日期时间格式, 不传参数默认 YYYY-MM-DD HH:mm:ss 格式 * 例: * dateUtil().format() * // 2022-06-16 11:56:02 * * // 不传入日期,默认以当前日期,格式化为特定格式日期 * dateUtil().format('YYYY年MM月DD日 (周W) HH时mm分ss秒') * // 2022年06月16日 (周四) 12时01分51秒 * * // 传入指定日期(string | date),格式化为指定格式日期(string) * dateUtil('2015.7.12').format('YYYY年MM月DD日 HH时mm秒ss分 星期W') * // 2015年07月12日 00时00分00秒 星期三 */ time = typeof time === 'string' ? time.replace(/-/g,'/') : time const date = isNaN(new Date(time)) ? time : new Date(time); return { date,format }; function format(rule = 'YYYY-MM-DD HH:mm:ss') { const weeks = ['日','一','二','三','四','五','六'] const padStart = (d) => (d + '').padStart(2,'0') const M = date.getMonth() + 1 + '' const D = date.getDate() + '' const H = date.getHours() + '' const m = date.getMinutes() + '' const s = date.getSeconds() + '' return rule .replace('YYYY',date.getFullYear()) .replace('MM',padStart(M)) .replace('M',M) .replace('DD',padStart(D)) .replace('D',D) .replace('HH',padStart(H)) .replace('H',H) .replace('mm',padStart(m)) .replace('m',m) .replace('ss',padStart(s)) .replace('s',s) .replace(/W/,weeks[date.getDay()]) .replace(/w/,date.getDay()) } } function toWithOpener(href,options = {}) { /** * 共享opener跳转 * @param { Object } router 如: * @param { Object } options 如: */ const { target = '_blank',routes } = options const win = window.open(href,target) // 设置新打开页面的面包屑 if (routes && Array.isArray(routes)) { const cloneRoutes = [...routes] cloneRoutes.shift() cloneRoutes[cloneRoutes.length - 1] = { ...cloneRoutes[cloneRoutes.length - 1], a: true, path: '/zhaopintong/' + location.hash, } win.sessionStorage.parent_routes = JSON.stringify(cloneRoutes) } return win } function downloadFile(href,fileName = '') { /** * 通过url一键下载图片 * @param { String } href 如: * @param { String } fileName 如: */ if (!href) { return } let aLink = document.createElement('a') aLink.download = fileName + Date.now() aLink.href = href aLink.click() } function base64ToBlob(base64Code) { /** * base64转Blob对象 * @param { String } code 如: */ const parts = base64Code.split(';base64,') const contentType = parts[0].split(':')[1] const raw = window.atob(parts[1]) const rawLength = raw.length const uint8Array = new Uint8Array(rawLength) for (var i = 0; i < rawLength; i++) { uint8Array[i] = raw.charCodeAt(i) } return new Blob([uint8Array],{ type: contentType }) } function base64ImgtoFile(base64Code,filename = 'file') { /** * base64转文件对象 * @param { String } base64Code 如: * @param { String } filename 如: */ let arr = base64Code.split(',') let mime = arr[0].match(/:(.*?);/)[1] let suffix = mime.split('/')[1] let bstr = atob(arr[1]) let n = bstr.length let u8arr = new Uint8Array(n) while (n--) { u8arr[n] = bstr.charCodeAt(n) } return new File([u8arr],`${filename}.${suffix}`,{ type: mime, }) } function isHasBtnPower(powerList = [],code = '') { /** * @description 判断角色是否有页面级按钮的权限 * @param {*} [powerList=[]] * @param {string} [code=''] * @returns {*} {boolean} */ if (!code) return false if (typeof code === 'string') code = [code] for (const value of code) { if (powerList?.includes?.(value)) return true } return false } function getBrowerEnv() { /** @描述 判断当前浏览器运行环境 */ const userAgent = window.navigator.userAgent.toLowerCase() const agents = ["Android","iPhone","SymbianOS","Windows Phone","iPad","iPod"] // 是否为支付宝环境 const isAliPay = /alipayclient/.test(userAgent) // 是否为淘宝环境 const isTaoBao = /windvane/.test(userAgent) // 是否为企业微信环境 const isWxWork = /wxwork/.test(userAgent) // 是否为微信环境 const isWeChat = /micromessenger/.test(userAgent) && !isWxWork // 是否为移动端 const isPhone = agents.some(x => new RegExp(x.toLocaleLowerCase()).test(userAgent)) return { isAliPay,isTaoBao,isWxWork,isWeChat,isPhone } } // function formatReportDataToStr(arr = [],headerLabel = []) { /** @描述 格式化报表数据拼接成字符串,以便复制到剪贴板 */ return arr.reduce( (pre,cur) => { return ( pre + headerLabel.reduceRight((pre2,cur2) => { return `${cur[cur2.key]}\t${pre2}` },'\n') ) }, headerLabel.reduceRight((pre,cur) => { return `${cur.title}\t${pre}` },'\n') ) } function copyStrToClipboard(value) { /** @描述 把字符串复制到剪贴板 */ const textarea = document.createElement('textarea') textarea.value = value document.body.appendChild(textarea) textarea.select() document.execCommand('Copy') document.body.removeChild(textarea) } async function copyStrToClipboardOfNavigator(value) { /** @描述 把字符串复制到剪贴板 */ return await navigator.clipboard.writeText(value) } function getPropertiesOfObj({ obj = {},keys = [] }) { /** * @描述 获取对象的指定属性集合 * @param {*} { obj = {}, keys = [] } * @returns {*} */ let newObj = {} keys.forEach((key) => { newObj[key] = obj[key] }) return newObj } function getLogObjectValue(arr,win = window) { /** @描述 定义以对象形式 获取window属性值 */ arr.forEach((newKey) => { Object.defineProperty(win,newKey,{ get() { return console.log('%O',win[newKey.slice(1)]) } }) }) } if (win.tl) { console.error('win.tl已经存在,请使用win.tls') if (!win.tls) win.tls = tools return } win.tl = tools Object.defineProperty(tools,'fns',{ /** @描述 对象下的函数名列表 */ get() { return Object.keys(tools) } }) })(window)