UNPKG

mtfunit

Version:

Mtfunit is a tiny JavaScript library that includes useful functions to operate strings and DOM

360 lines (294 loc) 17.5 kB
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <!-- Adding meta --> <!-- Adding external script--> <!-- Adding external style--> <!-- Adding scripts--> <!-- Adding style--> <!-- Adding overlay script--> <!-- Adding overlay style--> <title>mtfunit.js</title> <!--[if lt IE 9]> <script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script> <![endif]--> <link type="text/css" rel="stylesheet" href="styles/third-party/ionicons.min.css"> <link type="text/css" rel="stylesheet" href="styles/third-party/prettify-tomorrow.css"> <link type="text/css" rel="stylesheet" href="styles/jsdoc-default.css"> <link type="text/css" rel="stylesheet" href="styles/clean-jsdoc-theme-base.css"> <link type="text/css" rel="stylesheet" href="styles/clean-jsdoc-theme-light.css"> <svg aria-hidden="true" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" style="display:none"> <defs> <symbol id="copy-icon" viewbox="0 0 488.3 488.3"> <g> <path d="M314.25,85.4h-227c-21.3,0-38.6,17.3-38.6,38.6v325.7c0,21.3,17.3,38.6,38.6,38.6h227c21.3,0,38.6-17.3,38.6-38.6V124 C352.75,102.7,335.45,85.4,314.25,85.4z M325.75,449.6c0,6.4-5.2,11.6-11.6,11.6h-227c-6.4,0-11.6-5.2-11.6-11.6V124 c0-6.4,5.2-11.6,11.6-11.6h227c6.4,0,11.6,5.2,11.6,11.6V449.6z"/> <path d="M401.05,0h-227c-21.3,0-38.6,17.3-38.6,38.6c0,7.5,6,13.5,13.5,13.5s13.5-6,13.5-13.5c0-6.4,5.2-11.6,11.6-11.6h227 c6.4,0,11.6,5.2,11.6,11.6v325.7c0,6.4-5.2,11.6-11.6,11.6c-7.5,0-13.5,6-13.5,13.5s6,13.5,13.5,13.5c21.3,0,38.6-17.3,38.6-38.6 V38.6C439.65,17.3,422.35,0,401.05,0z"/> </g> </symbol> </defs> </svg> </head> <body> <input type="checkbox" id="nav-trigger" class="nav-trigger" /> <label for="nav-trigger" class="navicon-button x"> <div class="navicon"></div> </label> <label for="nav-trigger" class="overlay"></label> <nav> <h2><a href="index.html"><div class="text">Home</div></a></h2><div class="search-box"><input type="text" placeholder="Search..." id="search-box" /><div class="search-item-container" id="search-item-container"><ul class="search-item-ul" id="search-item-ul"></ul></div></div><div class="sidebar-list-div"><h3><a href="global.html">Global</a></h3><ul><li><a href="global.html#$">$</a></li><li><a href="global.html#addClass">addClass</a></li><li><a href="global.html#debounce">debounce</a></li><li><a href="global.html#delHtmlTag">delHtmlTag</a></li><li><a href="global.html#getAbsoluteUrl">getAbsoluteUrl</a></li><li><a href="global.html#htmlEncode">htmlEncode</a></li><li><a href="global.html#insertAfter">insertAfter</a></li><li><a href="global.html#isRefererValid">isRefererValid</a></li><li><a href="global.html#javaScriptEncode">javaScriptEncode</a></li><li><a href="global.html#query">query</a></li><li><a href="global.html#removeClass">removeClass</a></li><li><a href="global.html#removeItemByIndex">removeItemByIndex</a></li><li><a href="global.html#removeItemByValue">removeItemByValue</a></li><li><a href="global.html#removeNode">removeNode</a></li><li><a href="global.html#serialize">serialize</a></li><li><a href="global.html#stringifyJSON">stringifyJSON</a></li><li><a href="global.html#throttle">throttle</a></li></ul></div> </nav> <div id="main"> <h1 id='page-title' class="page-title">mtfunit.js</h1> <section> <article> <pre class="prettyprint source linenums"><code>/** * 获取指定的 querystring 中指定 name 的 value * @param {String} name 查询名 * @param {String} querystring 查询到的值 * @return {String|undefined} 查询到返回String,没有返回undefined */ function query (name, querystring) { if (name &amp;&amp; name.match(/(?:http[s]?:|^)\/{2}.*?(?:\.)/)) name = encodeURIComponent(name) // 仅编码Url const r = (querystring + '').match(new RegExp('(?:^|&amp;)\\s*?' + name + '\\s*=\\s*(.*?)\\s*(?:&amp;|$)')) return r === null ? undefined : decodeURIComponent(r[1]) } /** * 序列化对象,把对象转成URL查询字符串 * @param {Object} data 对象 * @return {String} 返回查询字符串 */ function serialize (data) { let queryString = [] Object.keys(data || {}).forEach(key => typeof key === 'string' &amp;&amp; queryString.push(encodeURIComponent(key) + '=' + encodeURIComponent(typeof data[key] === 'object' ? JSON.stringify(data[key]) : data[key]))) return queryString.join('&amp;') } /** * 根据选择器查找 DOM * @param {String} selector 选择器名称,用法同CSS选择器 * @return {DOM|Null|Array} 群组选择器(含,)返回Array。其他选择器,找到返回第一个DOM,没有返回Null */ function $ (selector) { if (!selector) return null let selectorStr = (selector + '').replace(/,$/, '') , i = -1 try { const nComma = selectorStr.split(',').length, r = document.querySelectorAll(selectorStr), res = [] if (nComma > 1) { while (++i &lt; nComma &amp;&amp; r[i]) res[i] = r[i] return res } return r[0] || null } catch (e) { return null } } /** * 删除 DOM 节点 * @param {DOM|ArrayLike} node 要删除的节点或节点列表 * @return {DOM|ArrayLike} 返回值被删除的节点或节点列表,与传参 node 相同 */ function removeNode (node) { return (node &amp;&amp; node.length ? Array.from(node) : [node]).map(node => node?.parentNode?.removeChild(node)), node } /** * 在 target 节点之后插入 node 节点 * @param {DOM|ArrayLike} node 要插入的节点或节点列表 * @param {DOM|Null} target 插入目标节点的后方,若目标节点不存在,则插入父节点的末尾 * @return {DOM|ArrayLike} 返回被插入的节点或节点列表,与传参 node 相同 */ function insertAfter (node, target) { if (!node || node.length === 0) return null let fragment = document.createDocumentFragment() if (node &amp;&amp; node.length) for (let i = 0; i &lt; node.length; i++) fragment.appendChild(node[i]) else fragment = node return (target?.parentNode || document.body).insertBefore(fragment, target?.nextSibling || null), node } /** * 添加类名 * @param {DOM|ArrayLike} node 要添加类名的节点或节点列表 * @param {String|Array} className 要添加的类名 * @return {DOM|ArrayLike} 返回添加类名的节点或节点列表,与传参 node 相同 */ function addClass (node, className) { return (node &amp;&amp; node.length ? Array.from(node) : [node]).map(node => node?.classList.add(className)), node } /** * 移除类名 * @param {DOM|Array&lt;Dom>} node 要移除类名的节点或节点列表 * @param {String|Array} className 要移除的类名 * @return {DOM|ArrayLike} 返回移除类名的节点或节点列表,与传参 node 相同 */ function removeClass (node, className) { return (node &amp;&amp; node.length ? Array.from(node) : [node]).map(node => node?.classList.remove(className)), node } /** * 获取绝对路径 * @param {String} url // 相对路径 * @return {String} // 返回路径的值与浏览器处理相对路径相同 */ function getAbsoluteUrl (url) { if (!url) return location.href url += '' const { origin, pathname } = location const stack = pathname.replace(/^\/|\/$/g, '').split('/') for (let i = 0, w = ''; i &lt;= url.length; i++) { const s = url[i] if (s === '/' || s === void 0) { if (w.substring(0, 2) === '..') { stack.pop() } else if (w !== '.') { i === 0 ? stack.length = 0 : stack.push(w) } w = '' } else w += s } return origin + '/' + stack.join('/') } /** * 防抖 * @param {Function} callback 回调函数 * @param {Number} time 延迟时间 * @return {Function} 防抖的函数 */ function debounce (callback, time) { let timer = null return function (...args) { if (timer) clearTimeout(timer) timer = setTimeout(() => { timer = null callback.apply(this, args) }, time + '' | 0 || 1000 / 60) } } /** * 节流 * @param {Function} callback 回调函数 * @param {Number} time 时间间隔 * @return {Function} 节流的函数 */ function throttle (callback, time) { let timer = null return function (...args) { if (timer) return timer = setTimeout(() => { timer = null callback.apply(this, args) }, time + '' | 0 || 1000 / 60) } } /** * 根据索引移出数组的某一项 * @param {Number} index 要删除的索引。正负和边界处理与Array.prototype.splice的第一参数相同 * @param {Array} arr 要操作的数组 * @return {Array} 返回操作后的数组 */ function removeItemByIndex (index, arr) { if (!arr || !arr.length || typeof index === 'bigint') return arr const n = arr.length index |= 0 if (index >= n) return arr if (index &lt; 0) index = index &lt;= -n ? 0 : index % n + n const r = Array(n - 1) for (let i = 0, j = 0; i &lt; n; i++) if (i !== index) r[j++] = arr[i] return r } /** * 根据值移出数组的某一项 * @param {Number} index 要删除的值。严格相等匹配与Array.prototype.indexOf相同 * @param {Array} arr 要操作的数组 * @return {Array} 返回操作后的数组 */ function removeItemByValue (value, arr) { if (!arr || !arr.length) return arr const n = arr.length, r = [] for (let i = 0, j = 0; i &lt; n; i++) if (arr[i] !== value) r[j++] = arr[i] return r } /** * JSON.stringify:保留对象中undefined、BigInt值和Function、Symbol结构 * @param {Object} obj JS对象 * @return {String} 返回序列化后的字符串 */ function stringifyJSON (obj) { const s = new Set(['undefined', 'bigint', 'function', 'symbol']) return JSON.stringify(obj, (_, v) => s.has(typeof v) ? String(v) : v) } /** * 富文本 → 纯文本 * @param {String} html 富文本字符串 * @return {String} 返回纯文本字符串 * ALL HTML TAG List Source:https://developer.mozilla.org/zh-CN/docs/Web/HTML/Element */ function delHtmlTag (html) { const TAG = 'html|base|head|link|meta|style|title|body|address|article|aside|footer|header|h1|h2|h3|h4|h5|h6|hgroup|main|nav|section|blockquote|dd|dir|div|dl|dt|figcaption|figure|hr|li|main|ol|p|pre|ul|a|abbr|b|bdi|bdo|br|cite|code|data|dfn|em|i|kbd|mark|q|rb|rp|rt|rtc|ruby|s|samp|small|span|strong|sub|sup|time|tt|u|var|wbr|area|audio|img|map|track|video|applet|embed|iframe|noembed|object|param|picture|source|canvas|noscript|script|del|ins|caption|col|colgroup|table|tbody|td|tfoot|th|thead|tr|button|datalist|fieldset|form|input|label|legend|meter|optgroup|option|output|progress|select|textarea|details|dialog|menu|menuitem|summary|content|element|shadow|slot|template|acronym|applet|basefont|bgsound|big|blink|center|command|content|dir|element|font|frame|frameset|image|isindex|keygen|listing|marquee|menuitem|multicol|nextid|nobr|noembed|noframes|plaintext|shadow|spacer|strike|tt|xmp' return ((html || '') + '').replace(new RegExp('&lt;\\/?(' + TAG + ')([\\s\\S]*?)>((?!&lt;)>)*', 'ig'), '') } /** * 转义:HTML → HTMLEntites * @param {String} html 富文本字符串 * @return {String} 返回转义后的字符串,转换非ASCII编码字符 */ function htmlEncode (html) { const h = { "10": "&lt;br/>", "32": "&amp;nbsp;", "34": "&amp;quot;", "38": "&amp;amp;", "39": "&amp;#x27;", "47": "&amp;#x2F;", "60": "&amp;lt;", "62": "&amp;gt;", "162": "&amp;cent;", "192": "&amp;Agrave;", "193": "&amp;Aacute;", "194": "&amp;Acirc;", "195": "&amp;Atilde;", "196": "&amp;Auml;", "197": "&amp;Aring;", "198": "&amp;AElig;", "199": "&amp;Ccedil;", "200": "&amp;Egrave;", "201": "&amp;Eacute;", "202": "&amp;Ecirc;", "203": "&amp;Euml;", "204": "&amp;Igrave;", "205": "&amp;Iacute;", "206": "&amp;Icirc;", "207": "&amp;Iuml;", "208": "&amp;ETH;", "209": "&amp;Ntilde;", "210": "&amp;Ograve;", "211": "&amp;Oacute;", "212": "&amp;Ocirc;", "213": "&amp;Otilde;", "214": "&amp;Ouml;", "216": "&amp;Oslash;", "217": "&amp;Ugrave;", "218": "&amp;Uacute;", "219": "&amp;Ucirc;", "220": "&amp;Uuml;", "221": "&amp;Yacute;", "222": "&amp;THORN;", "223": "&amp;szlig;", "224": "&amp;agrave;", "225": "&amp;aacute;", "226": "&amp;acirc;", "227": "&amp;atilde;", "228": "&amp;auml;", "229": "&amp;aring;", "230": "&amp;aelig;", "231": "&amp;ccedil;", "232": "&amp;egrave;", "233": "&amp;eacute;", "234": "&amp;ecirc;", "235": "&amp;euml;", "236": "&amp;igrave;", "237": "&amp;iacute;", "238": "&amp;icirc;", "239": "&amp;iuml;", "240": "&amp;eth;", "241": "&amp;ntilde;", "242": "&amp;ograve;", "243": "&amp;oacute;", "244": "&amp;ocirc;", "245": "&amp;otilde;", "246": "&amp;ouml;", "248": "&amp;oslash;", "249": "&amp;ugrave;", "250": "&amp;uacute;", "251": "&amp;ucirc;", "252": "&amp;uuml;", "253": "&amp;yacute;", "254": "&amp;thorn;", "255": "&amp;yuml;" } html = (html || '') + '' let r = '', t, i = -1 while (++i &lt; html.length) r += h[t = html.charCodeAt(i)] || (t > 127 ? `&amp;#x${t.toString(16).padStart(4, 0)};` : html[i]) return r } /** * 转义:JavaScript代码 → 字符串 * @param {String} js JavaScript代码 * @return {String} 返回转义后的字符串,转换非ASCII编码字符 */ function javaScriptEncode (js) { const h = { 8: '\\b', 9: '\\t', 10: '\\n', 12: '\\f', 13: '\\r', 34: '\\"', 38: '\\&amp;', 39: '\\\'', 47: '\\x2f', 60: '\\x3c', 62: '\\x3e', 92: '\\\\' } const isW = t => t > 47 &amp;&amp; t &lt; 58 || t > 64 &amp;&amp; t &lt; 91 || t > 96 &amp;&amp; t &lt; 123 // 大小写字母 + 数字(不含_) js = (js || '') + '' let r = '', t, i = -1 while (++i &lt; js.length) r += h[t = js.charCodeAt(i)] || (t > 127 ? `\\u${t.toString(16).padStart(4, 0)}` : isW(t) ? js[i] : `\\x${t.toString(16)}`) return r } /** * @param {String} referer 来源 * @param {Boolean} nullable 允许为空:默认允许 * @param {Array}} whiteList 白名单:域名 + 端口 白名单(不含http和https) */ function isRefererValid (referer, { nullable = true, whiteList = [] }) { const punycode = require('./punycode') return nullable &amp;&amp; !referer || RegExp('^http[s]?://(' + whiteList.map(v => { let [ host, port ] = v.split(':') if (port === void 0) port = '(443|80)' else if (port === '*') port = '\\d+' host = punycode.ToASCII(host).replace(/\*+(?!$)/g, '\\w+').replace(/\*+$/, '') return host + ':' + port }).join('|') + ')(\\?|/|$)').test( referer.replace(/(?&lt;=^http(s)?:\/\/[^:]*?)(\/|\?|$)/, (_, ssl, end) => ':' + (ssl ? 443 : 80) + end) ) } module.exports = { query, serialize, $, removeNode, insertAfter, addClass, removeClass, getAbsoluteUrl, debounce, throttle, removeItemByIndex, removeItemByValue, stringifyJSON, delHtmlTag, htmlEncode, javaScriptEncode, isRefererValid }</code></pre> </article> </section> </div> <footer id="footer"> </footer> <script src="scripts/third-party/prettify.js"></script> <script src="scripts/third-party/lang-css.js"></script> <script src="scripts/search.js"></script> <script src="scripts/third-party/fuse.js"></script> <script type="text/javascript" src="scripts/misc.js"></script> <script>prettyPrint();</script> <script src="scripts/linenumber.js"></script> <script src="scripts/fix-code-block.js"></script> <script> var list = [{"title":"$","link":"<a href=\"global.html#$\">Global &rtrif; $</a>"},{"title":"addClass","link":"<a href=\"global.html#addClass\">Global &rtrif; addClass</a>"},{"title":"debounce","link":"<a href=\"global.html#debounce\">Global &rtrif; debounce</a>"},{"title":"delHtmlTag","link":"<a href=\"global.html#delHtmlTag\">Global &rtrif; delHtmlTag</a>"},{"title":"getAbsoluteUrl","link":"<a href=\"global.html#getAbsoluteUrl\">Global &rtrif; getAbsoluteUrl</a>"},{"title":"htmlEncode","link":"<a href=\"global.html#htmlEncode\">Global &rtrif; htmlEncode</a>"},{"title":"insertAfter","link":"<a href=\"global.html#insertAfter\">Global &rtrif; insertAfter</a>"},{"title":"isRefererValid","link":"<a href=\"global.html#isRefererValid\">Global &rtrif; isRefererValid</a>"},{"title":"javaScriptEncode","link":"<a href=\"global.html#javaScriptEncode\">Global &rtrif; javaScriptEncode</a>"},{"title":"query","link":"<a href=\"global.html#query\">Global &rtrif; query</a>"},{"title":"removeClass","link":"<a href=\"global.html#removeClass\">Global &rtrif; removeClass</a>"},{"title":"removeItemByIndex","link":"<a href=\"global.html#removeItemByIndex\">Global &rtrif; removeItemByIndex</a>"},{"title":"removeItemByValue","link":"<a href=\"global.html#removeItemByValue\">Global &rtrif; removeItemByValue</a>"},{"title":"removeNode","link":"<a href=\"global.html#removeNode\">Global &rtrif; removeNode</a>"},{"title":"serialize","link":"<a href=\"global.html#serialize\">Global &rtrif; serialize</a>"},{"title":"stringifyJSON","link":"<a href=\"global.html#stringifyJSON\">Global &rtrif; stringifyJSON</a>"},{"title":"throttle","link":"<a href=\"global.html#throttle\">Global &rtrif; throttle</a>"}]; var options = setupSearch(list, options) </script> </body> </html>