UNPKG

vtils

Version:

一个面向业务的 JavaScript/TypeScript 实用程序库。

69 lines (61 loc) 2.67 kB
/* eslint-disable prefer-const */ // ref: https://github.com/sodatea/get-current-script/blob/main/index.js /** * 返回当前正在运行的脚本所属的 `<script>` 元素。有两点限制: * * - 只在脚本被解析后首次运行时有效; * - 如果当前正在执行的代码是被其他代码作为回调函数或者事件处理函数调用的,会返回 `null`。 */ export function getCurrentScript() { var descriptor = Object.getOwnPropertyDescriptor(document, 'currentScript'); // for chrome if (!descriptor && 'currentScript' in document && document.currentScript) { return document.currentScript; } // for other browsers with native support for currentScript if (descriptor && descriptor.get !== getCurrentScript && document.currentScript) { return document.currentScript; } // IE 8-10 support script readyState // IE 11+ & Firefox support stack trace try { throw new Error(); } catch (err) { // Find the second match for the "at" string to get file src url from stack. var ieStackRegExp = /.*at [^(]*\((.*):(.+):(.+)\)$/gi, ffStackRegExp = /@([^@]*):(\d+):(\d+)\s*$/gi, stackDetails = // @ts-ignore ieStackRegExp.exec(err.stack) || ffStackRegExp.exec(err.stack), scriptLocation = stackDetails && stackDetails[1] || false, line = stackDetails && stackDetails[2] || false, currentLocation = document.location.href.replace(document.location.hash, ''), pageSource, inlineScriptSourceRegExp, inlineScriptSource, scripts = document.getElementsByTagName('script'); // Live NodeList collection // try to find the matching external script first for (var i = 0; i < scripts.length; i++) { // If ready state is interactive, return the script tag if (scripts[i].readyState === 'interactive') { return scripts[i]; } // If src matches, return the script tag if (scripts[i].src === scriptLocation) { return scripts[i]; } } // if not found, the current script is likely inline if (scriptLocation === currentLocation) { pageSource = document.documentElement.outerHTML; inlineScriptSourceRegExp = new RegExp("(?:[^\\n]+?\\n){0," + (line - 2) + "}[^<]*<script>([\\d\\D]*?)<\\/script>[\\d\\D]*", 'i'); inlineScriptSource = pageSource.replace(inlineScriptSourceRegExp, '$1').trim(); // find the matching inline script for (var _i = 0; _i < scripts.length; _i++) { if (scripts[_i].innerHTML && scripts[_i].innerHTML.trim() === inlineScriptSource) return scripts[_i]; } } // If no match, return null return null; } }