该文写于 2013-08-22
在开辟过程当中,偶然须要动态猎取文件的 URL,猎取 JS 文件的 URL 是最常见的需求,例如像 Sea.js 等 Module Loader 就会用到。
现在常被用到的有以下几种体式格局,它们有各自的优缺点。
script 标签
经由过程猎取末了一个<script>
标签的src
属性来获得剧本文件的 URL。这类体式格局的症结点是正在实行的语句地点的 JS 文件是“当时末了的 JS 文件”。Sea.js 中就是用的此要领。
正因如此,瓶颈也在这里。这类体式格局只能在同一个文件中立即实行才有用,不能耽误实行及写成通用的 method 供其他地方挪用,不然猎取到的不一定是哪一个 JS 文件的 URL 了。不过这类体式格局的长处就是能够兼容各个浏览器。
javascript
function scriptPath() { var scripts = document.scripts; var script = scripts[ scripts.length - 1 ]; return script.hasAttribute ? script.src : // hack for IE8- // see http://msdn.microsoft.com/en-us/library/ms536429(VS.85).aspx script.getAttribute( "src", 4 ); } var url = scriptPath();
捕捉非常
这是一个从司徒正美的博文中看到的较为“智慧”的要领,利用了 exception 信息中会带有失足文件及位置的特点来猎取。
这类体式格局能够写为一个通用的 method,但其照样有两个较为严峻的缺点:
- 兼容性差,IE 和 Opera 基础都被倾轧在外
- 在挪用时必须在回调函数中抛出非常
javascript
function scriptPath( callback ) { var url = ""; if ( typeof callback === "function" ) { try { callback(); } catch( e ) { // Firefox if ( e.fileName ) { url = e.fileName; } // Safari else if ( e.sourceURL ) { url = e.sourceURL; } // Opera 9 else if ( e.stacktrace ) { url = (e.stacktrace.match( /\(\) in\s+(.*?\:\/\/\S+)/m ) || ["", ""])[1]; } // Chrome 4+/IE 10+ else if ( e.stack ) { url = (e.stack.match( /((http|file)\:\/{2,3}\S+\/\S+\.[a-z0-9]+)/i ) || ['',''])[1]; } } } return url; } // must throw an exception var url = scriptPath(function() { throw Error( "WTF!!!" ); });