2011-06-06 75 views
1

我使用此代碼
var anchors = document.getElementsByTagName("a"); 檢測HTML文檔中的錨點。有很多這樣的標籤。但alert(anchors.length)報告0.這似乎很奇怪。你知道可能是什麼問題嗎?Javascript檢測到零錨點

我使用這個代碼的Firefox擴展

var Highlighter = { 

... 
highlightLinks: function() { 
var anchors = document.getElementsByTagName("a"); 
... 
} 


window.addEventListener("DOMContentLoaded", function(e) { Highlighter.highlightLinks(); }, false); 

謝謝

+2

是dom加載? – 2011-06-06 16:06:39

+0

是你的頁面有效的html(或xhtml)嗎? – 2011-06-06 16:07:07

+0

我們需要更多的信息來解決這個問題... – codeomnitrix 2011-06-06 16:08:09

回答

2

在Firefox擴展,如果經由覆蓋到瀏覽器添加代碼,然後document是瀏覽器文件(browser.xul)而不是網頁的文檔。您可以通過content.document獲取網頁。

3

嘗試等待DOM像這樣:

window.onload = function() { 
    var anchor = document.getElementsByTagName('a'); 
    alert(anchor.length); 
} 
1

賠率是你需要有你的<script>標記作爲<body>中的最後一項,或者在加載所有內容後運行它們:<body onload="runStuff()">window.onload = function() { ... }$(document).ready(function() { ... });

+1

什麼是函數之前的[label](https://developer.mozilla.org/en/JavaScript/Reference/Statements/label)? – Quentin 2011-06-06 16:09:23

1

賠率,你必須在出現在<head>一個<script>元素的代碼,並沒有做任何拖延執行(如把它放在您致電onload函數)。

這意味着腳本會立即運行,此時DOM是半建立的,並且在腳本執行完成之後纔會存在任何內容。

2

當您使用功能,如getElementsByTagName,他們通過搜索DOM樹,因爲它是在那一刻和(在這種情況下)返回NodeList。如果你立即檢查length財產,它會告訴你有多少錨點右邊然後。如果此代碼位於文檔的head部分,則可能是該數字可能爲零。

如果您將代碼放在文檔的末尾,而所有的錨都在那裏,您應該看到不同的結果。 (注意:NodeList實例是活的,所以即使你在頂端抓取它,如果你在所有的錨已經創建時檢查它,它們應該在那裏。但是最好避免保留NodeList的引用時間過長的情況下,因爲事實上,他們正在現場表示,瀏覽器必須使它們保持最新,它可以成爲一個性能問題)

這裏的檢查太早的例子:

<!DOCTYPE html> 
<html> 
<head> 
<meta charset=utf-8 /> 
<title>Too early</title> 
<style> 
    body { 
    font-family: sans-serif; 
    } 
    p { 
    margin: 0px; 
    } 
</style> 
<script> 
    alert("Too early: " + document.getElementsByTagName('a').length); 
</script> 
</head> 
<body> 
    <a href="http://google.com">Google</a> 
    <a href="http://jsbin.com">JSBin</a> 
    <a href="http://stackoverflow.com">StackOverflow</a> 
</body> 
</html> 

Live copy

而且檢查時,文檔的完全加載(唯一的變化是在script標籤):

<!DOCTYPE html> 
<html> 
<head> 
<meta charset=utf-8 /> 
<title>Too early</title> 
<style> 
    body { 
    font-family: sans-serif; 
    } 
    p { 
    margin: 0px; 
    } 
</style> 
</head> 
<body> 
    <a href="http://google.com">Google</a> 
    <a href="http://jsbin.com">JSBin</a> 
    <a href="http://stackoverflow.com">StackOverflow</a> 
<script> 
    alert("Fully loaded: " + document.getElementsByTagName('a').length); 
</script> 
</body> 
</html> 

Live copy

可以把你的腳本更高處,然後等待運行它。一種常見的方法是使用window.onload,但要知道,該事件後會在頁面加載序列非常非常晚所有圖像和其他資源有完全下載。有時候這就是你想要的,但更多的時候你想更早做些事情。大多數庫提供了一個「準備就緒」或「DOM加載」事件發生在早期,但是否要使用它們將取決於你在做什麼。 Google的Closure庫甚至沒有提供它(他們不認爲它應該,他們認爲最好把腳本放在最後;請參閱下面的鏈接)。

您在評論中詢問是否將腳本放入head標記是最佳做法。這是一個常見的神話。事實上,在head部分中使用腳本,可以在瀏覽器向用戶顯示任何內容之前處理(下載,解釋)腳本,從而減緩頁面的顯式加載時間。即使使用window.onload,瀏覽器仍然需要下載並解釋您的腳本,然後等待,直到load事件觸發運行爲止。查看我添加的鏈接,除非有一個很好的理由,讓腳本儘早加載(有一些)的最佳做法是在body標記的末尾加載腳本。

更多:

有有時你需要至少一些腳本上最主要原因,最關鍵的是如果你需要連接一些默認處理的東西,用戶可能會在頁面顯示給他們之後點擊,但在瀏覽器完成檢索你的sc之前撕裂,解釋它,並連接你的事件處理程序!這是「用戶點擊太早」的問題。你如何處理這個問題取決於你的頁面和你的傾向。對付它的上面方法是:

  1. 確保一切正常沒有JavaScript,然後提供一個更好的接口,當/如果你的JavaScript加載。這被稱爲「漸進式增強」,其主要原因不是用戶點擊過早的問題,它是爲了支持因各種原因而沒有啓用JavaScript的用戶的所有。但好的是,它也有助於解決這個問題。
  2. 使用文檔頂部的一小段內聯腳本(而不是單獨的文件)將點擊排隊(或僅僅拒絕),從而連接文檔範圍的點擊處理程序。我的首選到目前爲止是將它們排隊(包括用戶所做的某種指示符),然後在加載JavaScript時處理它們。用戶不喜歡它,當點擊無所作爲時。請注意,如果用戶禁用了JavaScript,這可以很好地與漸進式增強功能結合使用。
  3. 在用戶運行JavaScript之前,用戶可以與之交互的內容沒有任何意義。對JavaScript禁用的用戶不友好,但有理由。這與漸進式增長之間的界限是模糊的,基本上它是漸進式的增強,如果頁面仍然能夠在沒有JavaScript的情況下發揮作用,並且如果不是這樣的話,這是無名的較少選項。
  4. 確保頁面加載速度如此之快,並且腳本加載速度如此之快以至於無關緊要。但要小心連接速度慢和用戶快速。;-)
+0

將函數放在window.onload中會更好嗎?我一直認爲經驗法則是在'head'部分有所有的JavaScript。 – Sparafusile 2011-06-06 16:11:48

+0

@Sparafusile:這是一個常見的神話。我已經通過討論更新了答案。 – 2011-06-06 16:21:42