2015-06-14 56 views
0

我有一個Chrome擴展,需要瀏覽網頁上的每個<p></p>。我的Chrome擴展插件查看p文本並檢查文本是否位於數組中。問題是,該陣列有超過3000個元素,如果可能的話,我非常想要達到12,000或更多。

以目前的速度,這是不可行的,因爲它需要網頁約4秒多加載頁面。我的Chrome擴展在文檔的末尾運行,因此用戶可以在技術上瀏覽網站,只需要4秒鐘就可以加載所有內容。

這裏是我的代碼:

$.each(arrayObj, function(key, value) { 
     $("p").highlight(key, {caseSensitive: true, className: 'highlight-882312', wordsOnly:true }); 
}); 

$('.highlight-882312').each(function() {  

    var currentKey = $(this).text(); 
    console.log(currentKey); 

//do something else here that doesn't really 
//apply to the question as it only runs when the user hovers over the class. 

}); 

,然後陣列看起來像這樣很簡單:

var arrayObj = { 

"keyword1": 'keyword_1_site', 
"keyword2": 'keyword_2_site', 
... etc 
... 3,000+ more lines ... 
... 

} 

我假設$.each是不是最有效的,正如我所說,加載4秒是相當多的。有什麼我可以做的,以提高效率?我能否在陣列中擊中12,000行?

謝謝:)

+0

,如果你需要,你可以使用一些研究算法,就像二分搜索的搜索方法。 – Drago96

回答

0

試試這個:

var p = $("p"); 
$.each(arrayObj, function(key, value) { 
    p.highlight(key, {caseSensitive: true, className: 'highlight-882312', wordsOnly:true }); 
}); 

$('.highlight-882312').each(function(idx, element) {  
    var currentKey = element.text(); 
    console.log(currentKey); 

    // other stuff 
}); 

一般來說,要避免內部循環$()選擇,因爲他們是費時。請注意,each()的回調接收正在迭代的元素,並且不需要再次選擇它。

此解決方案可能無法完全解決您的問題,但至少是最有效的方式,可以在不知道更多細節的情況下進行思考。

0

這裏有一對夫婦的想法:

  • $("p").highlight()選項是靜態的,所以一次定義,多次使用。
  • 僅將.highlight()應用於頁面上實際存在的單詞。
var options = { 
     caseSensitive: true, 
     className: 'highlight-882312', 
     wordsOnly:true 
    }, 
    arrayObj_ = {}, 
    $p = $("p"); 

//Populate arrayObj_ with true for every word that exists on the page 
$p.each(function() { 
    $(this).text().split(' ').forEach(function(word) { 
     arrayObj_[word] = true; 
    }); 
}); 

//Now loop through arrayObj_ , 
// which is hopefully much smaller than arrayObj, 
// and highlight those words that are represted as keys in arrayObj. 
$.each(arrayObj_, function(key, value) { 
    if(arrayObj[key]) { 
     $p.highlight(key, options); 
    } 
}); 

不知道這是否將是更快或更慢。您將需要運行測試。

編輯...

更妙的是,發現在單次單詞和亮點。

var options = { 
     caseSensitive: true, 
     className: 'highlight-882312', 
     wordsOnly:true 
    }, 
    wordsFound = {}, 
    $p = $("p"); 

$p.text().split(/\b/).forEach(function(word) { 
    if(!wordsFound[word]) { 
     wordsFound[word] = true; 
     if(arrayObj[word]) { 
      $p.highlight(word, options); 
     } 
    } 
}); 
0

它們重構爲JavaScript for循環,而不是jQuery的each環。 https://stackoverflow.com/a/14808512/1547497

var elems = $('.highlight-882312'); 
for (var i = 0; i < elems.length; ++i){ 

} 
+0

我試圖將我的'每個'數組轉換爲for循環,但它似乎並沒有爲我工作..你能引導我進入正確的方向基於我的'每個'在循環中? – Simon

+0

jQuery在該塊上的'each'方法引起的開銷是一個小問題,與之前在每個循環中進行'$()'選擇的迭代相比...在我的回答中,我提出了一種避免這種操作的不同策略。 – ggalmazor

0

正在運行用於在陣列中的每個元件全球選擇器。這相當多。

所以至少我會建議更換此:

$.each(arrayObj, function(key, value) { 
     $("p").highlight(key, ...); 
}); 

本:

var $all_p = $("p"); 

$.each(arrayObj, function(key, value) { 
    $all_p.highlight(key, ...); 
}); 
+0

我給了它一個..似乎沒有影響表現真的...... – Simon