我在一個舊的aspx網頁上的JS檔案中有一個簡單的for-loop:
function SaveCurrentFilterDisplay() {
var currentFilterCode = document.getElementById('curfilt').value。
var currentFilterList, currentFilterDisplay;
var i, str;
if (currentFilterCode != ''/span>) {
currentFilterList = document.getElementById(currentFilterCode) 。
currentFilterDisplay = document.getElementById(currentFilterCode '_display')。
//save the previous filter text names[/span].
//alert(currentFilterCode ': ' currentFilterList.length);
if (currentFilterList.length) {
//multi-select list[/span
str = '';
for (i = 0; i < currentFilterList.length; i ) {
if (currentFilterList.options[i].selected) {
if (str.length > 0) {
str = str ', '/span>
}
str = str currentFilterList.options[i].text。
}
}
} else {
//text field
str = currentFilterList.value。
}
alert(' finished looping')。
currentFilterDisplay.value = str;
}
return true。
}
有時這個回圈要回圈近50000次。其他情況下,只需要幾百次或更少。
讓我感到困惑的是,當這個回圈必須回圈 50,000 次并且我在 Chrome 瀏覽器中運行這個回圈時,它需要 2 分鐘左右。但是當我在 IE 中做完全相同的事情時,只需要幾秒鐘,有時甚至看起來是瞬間完成的。
我想知道是否有一種解釋與基于 Chrome 的瀏覽器處理 Javascript 的方式有關?
編輯:對于如何優化這個問題,以便在 Chrome 瀏覽器中不需要花費 2 分鐘,或許有什么建議?
編輯2:我已經更新了我的問題,以顯示整個函式。當我使用 Chrome 瀏覽器的開發工具瀏覽該函式時,該方法中的所有陳述句都會立即執行,但當我瀏覽回圈時,需要花費 2 分鐘來處理警報陳述句,因此花費 2 分鐘的是回圈。
下面是一些 HTML,顯示了 currentFilterList 被指向的內容:
<select id="ID"/span> name="adv"/span> multiple="true"/span>>
<option value="1"/span>>。 選項1</選項>/span>
<option value="2"/span>> 選項2</選項>/span>
<option value="3"/span>> 選項3</option>
</select>
所以作為一個例子,currentFilterCode = "ID"。這使得currentFilterList設定為上面的選擇串列(由于明顯的原因,比真正的串列短得多)。
最終編輯:在評論的幫助下,我確實發布了我對我所面臨的特定問題的解決方案。這并不是處理類似情況的最佳方法,但它在我所從事的應用程式的限制下是可行的。我選擇了另一個答案作為解決方案,因為這是在類似情況下應該采取的方法。
uj5u.com熱心網友回復:
那么,既然我們可以用選擇器來做,為什么還要回圈尋找選擇呢?使用map和join來建立一個由選擇值組成的字串。
。document.querySelector("#select1"/span>) 。 addEventListener("change", () => {
const out = [...document.querySelectorAll('#select1 option:checked') ] 。 map(x => x.text)。
console.log(out.join(' , '))。
});
/*
document.querySelector("#select1").addEventListener("change", function() {
var out = Array.from(document.querySelectorAll('#select1 option:checked')).map(function(x) { return x.text; });
console.log(out.join(', '))。
});
*/
< select id="select1" multiple>/span>
<option>/span>FOO1</option>/span>
<option>/span>FOO2</option>/span>
<option>/span>FOO3</option>/span>
<option>/span>FOO4</option>/span>
<option>/span>FOO5</option>/span>
<option>/span>FOO6</option>/span>
<option>/span>FOO7</option>/span>
<option>/span>FOO8</option>/span>
<option>/span>FOO9</option>/span>
<option>/span>FOO10</option>/span>
</select>/span>
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" class="snippet-box-edit snippet-box-result" frameborder="0"></iframe>
或用所選的選項和地圖并加入
。document.querySelector("#select1"/span>) 。 addEventListener("change", () => {
var out = [...document.querySelector('#select1')。 selectedOptions].map(x => x.text) 。
console.log(out.join(', ')) 。
});
< select id="select1" multiple>/span>
<option>/span>FOO1</option>/span>
<option>/span>FOO2</option>/span>
<option>/span>FOO3</option>/span>
<option>/span>FOO4</option>/span>
<option>/span>FOO5</option>/span>
<option>/span>FOO6</option>/span>
<option>/span>FOO7</option>/span>
<option>/span>FOO8</option>/span>
<option>/span>FOO9</option>/span>
<option>/span>FOO10</option>/span>
</select>/span>
<iframe name="sif2" sandbox="allow-forms allow-modals allow-scripts" class="snippet-box-edit snippet-box-result" frameborder="0"></iframe>
uj5u.com熱心網友回復:
首先,向在評論中與我一起作業的每個人致敬,因為我試圖繞過我試圖優化的丑陋遺留代碼。多虧了他們,我才找到了解決方案。
該問題與從回圈中的第i個個選項中獲取屬性有關。
我發現了這篇優秀的文章。https://idiallo.com/javascript/minimize-lookups-in-for-loops
其中提到了幾種優化訪問DOM元素的回圈的方法,比如我正在處理的那個。作者提到了創建和重新分配變數是如何減慢速度的(閱讀真實的東西,我沒有做到這一點)。修復方法是在回圈之外創建變數并使用它們。在應用了這些改變之后,我得到了以下結果:
function SaveCurrentFilterDisplay() {
var currentFilterCode = document.getElementById('curfilt').value。
var currentFilterList, currentFilterDisplay;
var i = 0, str, numOptions, selectedOptions;
if (currentFilterCode != ''/span>) {
currentFilterList = document.getElementById(currentFilterCode) 。
currentFilterDisplay = document.getElementById(currentFilterCode '_display')。
selectedOptions = currentFilterList.selectedOptions;
numOptions = selectedOptions.length;
if (selectedOptions.length) {
str = ''/span>;
for (; i < numOptions; i ) {
if (str.length > 0) {
str = str ', '/span>
}
str = str selectedOptions[i].text;
}
} else {
str = currentFilterList.value;
}
currentFilterDisplay.value = str;
}
作者提到,性能的提升將是可以忽略不計的。然而,就像所有閱讀這篇文章的人一樣,他可能沒有考慮到在一個長達 50,000 個選項的選擇串列中進行回圈!
現在,這個方法已經運行在一個長長的選擇串列中。
現在,在不到一秒鐘的時間內,這個方法就能運行完這 50,000 個專案!
編輯:已編輯的內容包括
編輯:正如評論中提到的那樣,編輯后使用了 selectedOptions。這就是我如何讓這個舊網頁作業的。很明顯,這不是一個最好的解決方案,但它在應用程式的其他部分對我的限制范圍內起作用。
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/320188.html
標籤:
