獲取 JavaScript 腳本文件路徑

該文寫於 2013-08-22javascript

在開發過程當中,有時須要動態獲取文件的 URL,獲取 JS 文件的 URL 是最多見的需求,例如像 Sea.js 等 Module Loader 就會用到。html

目前常被用到的有如下幾種方式,它們有各自的優缺點。java

script 標籤

經過獲取最後一個<script>標籤的src屬性來獲得腳本文件的 URL。這種方式的關鍵點是正在執行的語句所在的 JS 文件是「當時最後的 JS 文件」。Sea.js 中就是用的此方法。瀏覽器

正因如此,瓶頸也在這裏。這種方式只能在同一個文件中即時執行纔有效,不能延遲執行及寫成通用的 method 供其餘地方調用,不然獲取到的不必定是哪一個 JS 文件的 URL 了。不過這種方式的優勢就是可以兼容各個瀏覽器。ruby

javascriptfunction 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,但其仍是有兩個較爲嚴重的缺陷:url

  1. 兼容性差,IE 和 Opera 基本都被排擠在外
  2. 在調用時必須在回調函數中拋出異常
javascriptfunction 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!!!" );
    });
相關文章
相關標籤/搜索