網頁制作Poluoluo文章簡介:JS教程:給JavaScript文件傳遞參數.
這是最簡單的一種方式,比如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 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特殊照顧了,甚至直接通過某種高級傳送門就把參數傳過去了……