JS教程:給JavaScript檔案傳遞參數

來源:互聯網
上載者:User

一、利用全域變數

這是最簡單的一種方式,比如Google Adsense:

<script type="text/javascript">google_ad_client = 'pub-3741595817388494';</script><script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script>

缺點是引入了全域變數。其中引入檔案的方式還有兩個變體:

// 變體1:用document.write輸出<script type="text/javascript">google_ga_id = 'g6u7un8646xx';document.write(unescape('%3Cscript type="text/javascript" src="http://www.google-analytics.com/ga.js"%3E%3C/script%3E'));</script>// 變體2:用DOM操作append到head裡<script type="text/javascript">G_BEACON_ATP = 'category=&userid=&channel=112ad_id=';document.getElementsByTagName('head')[0].appendChild(document.createElement('script')).src='http://taobao.com/atp.js';</script>// 注意:上面的代碼是根據實際應用虛擬示範代碼

註:變體1應用很多,常見寫法如下:

<script type="text/javascript">// 直接轉義即可:document.write('<script type="text/javascript" src="test.js"></script>');// 或者像Yahoo!首頁一樣:document.write('<scr' + 'ipt type="text/javascript" src="test.js"></scr' + 'ipt>');</script>

二、擷取並解析script元素的src

和全部變數相比,我們更希望能像下面這樣傳入參數:

<script type="text/javascript" src="test.js?a=b&c=d"></script>

核心問題是如何擷取到src屬性。

方法一是給script添加id屬性,通過id得到當前script,再用正則從src中取出參數。缺點是HTML 4.01 Specification裡,SCRIPT元素沒有id屬性。這個缺點也算不得是缺點,畢竟盡信標準不如無標準。

方法二是用js的檔案名稱當作鉤子,js代碼裡通過document.getElementsByTagName('script')後,正則匹配出當前js檔案。這個方法很正統,但要求檔案名稱唯一。缺點是代碼多,不精鍊,對效能也稍有影響。

方法三是在方法一的基礎上,乾脆再添加一個自訂屬性data:

<script id="testScript" type="text/javascript" src="test.js" data="a=b&c=d"></script>

test.js檔案裡,通過下面這行得到傳入的參數:

var scriptArgs = document.getElementById('testScript').getAttribute('data');

方法四是利用js的順序執行機制(js檔案的載入可以是同步或非同步方式,但執行時,一定是按照在文檔流中的順序來執行的)。當某個js檔案執行時,一定是“已載入”的js檔案中的最後一個:

var scripts = document.getElementsByTagName('script');var currentScript = scripts[scripts.length - 1];

方法四比方法二更靈巧天才。

從代碼的精簡和效能上講,方法三 > 方法 一 > 方法四 > 方法二

小結:如果你很在意標準,推薦方法四;如果和我一樣覺得沒必要完全遵守標準,推薦方法三。

三、靈感方案

如果你和我一樣是John Resig的忠實fans,或許還記得去年8月份討論得很火爆的《Degrading Script Tags》。John Resig給我們開啟了一扇想象的門,對於本文的問題來說,還可以用以下“邪門歪道”來實現:

<script type="text/javascript" src="test.js">    TB.SomeApp.scriptArgs = 'a=b&c=d';</script>

在test.js檔案裡:

TB = {}; TB.SomeApp = {};var scripts = document.getElementsByTagName("script");eval(scripts[ scripts.length - 1 ].innerHTML);

這樣就將參數儲存到了TB.SomeApp.scriptArgs變數裡。

當參數不多時,甚至可以這樣:

<script type="text/javascript" src="test.js">a=b&c=d</script>

js檔案裡:

var scripts = document.getElementsByTagName("script");var scriptArgs = scripts[ scripts.length - 1 ].innerHTML.replace(/[s]/g, '');

想象是無止境的,還可以利用onload:

<script type="text/javascript" src="test.js" onload="TB.SomeFun('a=b&c=d')"></script>

js檔案裡定義好函數即可:

TB = {};TB.SomeFun = function(arg) { //code };

上面的代碼在非ie瀏覽器下,都能正確運行。針對笨笨的ie,還得加幾行代碼:

if(window.ActiveXObject) {    var scripts = document.getElementsByTagName('script');    eval(scripts[scripts.length - 1].getAttribute('onload'));}

只要繼續發揚挖掘精神,我相信還有更多靈感方案-.-

總結

看了上面這麼多解決方案,究竟哪個方案最好呢?我的答案是:沒有最好,只有最合適!因為對於不同的應用,以及不同的理念來說,對“好”的定義是各異的。

比如我當前的理念,覺得沒必要完全遵守標準,而全域變數,要避免的是濫用,不是不用。因此我會選擇全域變數方案,最簡單,效能也最好。

如果是我的同事小馬,很遵從標準,或許就會選擇第二類方案中的方法二或方法四。

再或者等小雕長大了,也許直接就用onload方案同時不用再給ie特殊照顧了,甚至直接通過某種進階傳送門就把參數傳過去了……

參考資料

  • Dynamically Loading External JavaScript Files(看完,你就能理解document.write裡,script標籤為何要轉義)
  • Passing JavaScript arguments via the src attribute(很系統也很正統的討論了如何給js檔案傳遞參數)
  • Degrading Script Tags(John Resig總能從機理上讓人看清很多問題)
  • On-Demand Javascript(累就別看,瞄一眼就行)


聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.