![](/img/trans.png)
[英]The addEventListener does not work in external Javascript file, but does when placed directly on ASP page. Why?
[英]I keep everything in an external .js file. But not all functions are used on every page. Does this affect speed?
我的應用程序的JavaScript / jQuery包含在一個外部scripts.js
文件中。 通常看起來像這樣:
$('document').on('ready', function() {
giraffe();
elephant();
zebra();
});
function giraffe() {
// code
}
function elephant() {
// code
}
function zebra() {
// code
}
giraffe()
僅用於/animal/giraffe
可用的視圖
elephant()
僅用於/animal/elephant
可用的視圖
zebra()
僅用於/animal/zebra
的視圖,
但是所有這3個都應該在可用的/animal/all
視圖上運行。 這是一個簡單的示例,但這是將它們全部保存在一個.js
文件中的原因,除了將HTTP請求保持在最低限度之外。
我的問題是,這會影響JavaScript渲染嗎? 即使未在/animal/zebra
上使用giraffe()
(沒有要處理的元素),仍在調用它。 如果JS / jQuery沒有任何作用,它會忽略該函數嗎? 我確定已讀取整個腳本,這可能需要時間。 那么,處理此問題的最佳方法是什么?
為了避免沖突,我在js文件的頂部創建了條件語句,以僅運行活動頁面所需的功能:
$('document').on('ready', function() {
var body = $('body');
if( body.hasClass('giraffe') ) {
giraffe();
}
if( body.hasClass('elephant') ) {
elephant();
}
if( body.hasClass('zebra') ) {
zebra();
}
});
這比我想要的更為冗長,但是可以成功地使這些功能保持模塊化/無沖突。 我歡迎對此解決方案進行改進。
當然,只運行所需的代碼會更好。 這並不困難; 唯一的次要復雜性是處理/animals/all
情況。 如果要將所有代碼保存在一個文件中,可以采用以下方式:
var animals = {
giraffe: function() {
console.log( "I'm a giraffe" );
},
elephant: function() {
console.log( "I'm an elephant" );
},
zebra: function() {
console.log( "I'm a zebra" );
}
};
$(function() {
var animal = location.pathname.split('/').pop();
if( animal == 'all' ) {
for( var animal in animals ) {
animals[animal]();
}
}
else if( animal in animals ) {
animals[animal]();
}
else {
console.log( "I'm a mystery animal" );
}
});
您實際上可以通過在Stack Overflow上轉到如下所示的URL來測試該代碼,然后將該代碼粘貼到JavaScript控制台中:
https://stackoverflow.com/animal/giraffe
https://stackoverflow.com/animal/elephant
https://stackoverflow.com/animal/zebra
https://stackoverflow.com/animal/ocelot
https://stackoverflow.com/animal/all
更新:好的,因此您在評論中解釋了實際情況要復雜一些。 如果對任何人都有用,我將在此處保留此代碼,但是對於您的情況,您可能更接近於已經擁有的代碼所需要的內容。
WRT的問題是,當您在與頁面無關的頁面上使用哪種動物功能時,當然取決於它的編碼方式。 它可能無法成功執行任何操作,或者可能有錯誤,對吧?
由於我們在談論jQuery代碼,因此這里有兩個示例。 假設您有按ID查找元素的代碼,然后假定該元素存在:
var zebraElement = $('#zebra')[0];
console.log( zebraElement.value );
在#zebra
元素存在的頁面上,此代碼將記錄其value
屬性。 (我為討論起見,它是一個具有值的元素,例如輸入元素。)
但是,如果#zebra
不存在,那么zebraElement
是undefined
,並且attemping訪問其value
在調試器將失敗和土地。
OTOH,如果您這樣編碼:
var $zebra = $('#zebra');
console.log( $zebra.val() );
如果缺少#zebra
,它不會失敗,它將成功打印undefined
而不會引起錯誤。
類似地,如果您有使用$().each()
,則當缺少元素時,它將通常不會失敗地運行,因為它根本不會執行回調函數:
$('.animal').each( function( i, e ) {
console.log( $(e).val() );
});
如果沒有元素帶有class="animal"
,則將永遠不會到達console.log()
調用。 因此沒有錯誤,它什么也不做。
根據您的操作,這可能是一種完全合理的方法,它僅觸發您需要的行為—只需確保您的代碼通過不做任何事情即可處理丟失的DOM元素。
另外,請務必閱讀nick的答案以獲得更多見解。
還有一個更新…在注釋中,您提到了在body
元素上鍵入類名。 做到這一點的一種好方法類似於上面的代碼示例。 您不需要為每個動物設置條件,只需一個循環和一個條件即可:
var animals = {
giraffe: function() {
console.log( "I'm a giraffe" );
},
elephant: function() {
console.log( "I'm an elephant" );
},
zebra: function() {
console.log( "I'm a zebra" );
}
};
$(function() {
var $body = $('body');
for( var animal in animals ) {
if( $body.hasClass(animal) ) {
animals[animal]();
}
}
});
因此,例如,如果您具有<body class="giraffe zebra">
,它將調用animals.giraffe()
和animals.zebra()
函數。
實際上,這里有兩個問題,一個是是否加載所有功能,另一個是是否運行所有功能。 Michael Geary在其他答案中已經很好地解決了有關是否全部運行它們(以及僅運行所需功能的一些解決方案)的問題。
那么,您應該全部加載它們嗎? 您需要權衡下載更大文件所需的時間,而不是提出額外的http請求。 只有3個“組”的功能在3個頁面之間共享(並且一個頁面使用所有這些功能),並且當您希望用戶定期更改頁面時,我會使用一個文件。
一旦項目變得很大,您將需要使用requirejs之類的工具來管理腳本並異步加載它們。 異步加載js腳本會提高頁面的速度(以及頁面的感知速度),如果出現問題(尤其是第三方托管的腳本),您的頁面將無法獲得幫助。 您當然可以在沒有庫的情況下執行此操作:
使用HTML5:
<script async src="http://google.com/script.js"></script>
有上百萬種使用純JS異步加載的方式,一種方式是:
<script>
var resource = document.createElement('script');
resource.src = "//google.com/script.js";
var script = document.getElementsByTagName('script')[0];
script.parentNode.insertBefore(resource, script);
</script>
Javascript將忽略任何未“調用”的函數。 就是 如果您沒有在/ elephant或/ all頁面以外的任何頁面上都不調用Elephant(),則它將永遠不會使用,也不會給您帶來任何錯誤。
但是,您可能不希望在不用於快速加載頁面的頁面上不顯示功能。 考慮為某些頁面分離JS文件,或者通過從諸如PHP之類的后端服務器加載某些JS腳本來確定需要哪些功能。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.