2012-02-03 166 views
28

所以,我需要知道javascript的元素的寬度,我遇到的問題是該函數過早觸發,寬度在css被應用時發生更改。據我瞭解,$(document).ready()函數在文檔完成時被解僱,但似乎並沒有像那樣工作。

不管怎麼說,我敢肯定,我的問題可以理解的代碼(這是一個簡單的例子):

<html> 
<head> 
    <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script> 
    <link href='http://fonts.googleapis.com/css?family=Parisienne' rel='stylesheet' type='text/css'> 

    <style type="text/css"> 
     #target { 
      font-family: 'Parisienne', cursive; 
      float: left; 
     } 
    </style> 
</head> 
<body> 
    <div id="target">Element</div> 
</body> 
</html> 

<script type="text/javascript"> 
    $(document).ready(function(){ 
     console.debug($('#target').outerWidth()); 
     alert('hold on'); 
     console.debug($('#target').outerWidth()); 
    }); 
</script> 

我想知道#target div的寬度,問題是,在alert之前執行的代碼會給出與之後不同的輸出,這可能是因爲字體未完全加載,並且它使用默認字體測量div。

它可以像我期望的那樣在Google Chrome中使用,但不會在IE和Firefox上使用。

+0

我可以確認2013年11月24日,這個問題jQuery的2.X仍然存在,當你點擊瀏覽器的刷新按鈕。轉到此[小提琴](http://jsfiddle.net/jLDbX/)。當你第一次加載小提琴時,一切都應該在大多數時候都正常工作。如果將鼠標放在URL中並按回車,它也可以工作。但是如果你點擊刷新按鈕或點擊* CTRL + R *,事情就會變得糟糕透了。 – 2013-11-24 11:48:15

+0

我試圖實現一個「倒計時鎖存器」來測量寬度和高度,只有當窗口負載被觸發和依賴字體完成觸發時。看看是否有幫助:[http://jsfiddle.net/jLDbX/1/](http://jsfiddle.net/jLDbX/1/)。在這個小提琴中,一切看起來都是正確的。但在我的真實世界的應用程序中,我不斷收到錯誤。對你來說,它可能會起作用。 – 2013-11-24 13:10:29

回答

58

如果你依賴於外部內容被已經被加載(如圖片,字體),您需要使用window.load事件

$(window).load(function() { 
    // code here 
}); 

這些事件的行爲this article描述。

+5

兩年後,仍然有幫助! – statue 2014-01-30 15:32:45

+5

在JQuery 3.0中,應該使用'$(window).on('load',function(){ });'由於$(window).load()已被棄用。 – 2016-07-21 06:06:15

+0

@AlexH,好點。 '$(window).load()'在jQuery 1.8中被棄用。此外,這是令人困惑的,因爲在jQuery中有兩個'.load()'方法(在事件處理被移除之前)。 – ryanpcmcquen 2017-12-15 12:54:15

9

報價OP:

「正如我理解,文檔被完成時$(document).ready()功能被解僱,」

$(document).ready()火災時,所述DOM(「文檔對象模型「)已完全加載並準備好進行操作。 DOM與「文檔」不一樣。

W3C - DOM Frequently Asked Questions

您可以嘗試$(window).load()功能,而不是...

$(window).load(function() { 
    // your code 
}); 

它會等待所有頁面的資源(如圖片和字體等)發射之前完全加載。

3

jQuery .ready()函數在DOM完成後立即觸發。這並不意味着所有的資產(如圖片,CSS等)都已經加載,因此元素的大小可能會發生變化。

如果您需要元素的大小,請使用$(window).load()。

1

您可以使用$(window).load(),但會等待所有資源(例如圖像等)。如果你只是想等待加載的字體,你可以嘗試這樣的事:

<script type="text/javascript"> 
    var isFontLoaded = false; 
    var isDocumentReady = false; 
    $("link[href*=fonts.googleapis.com]").load(function() { 
     isFontLoaded = true; 
     if (isDocumentReady) { 
      init(); 
     } 
    }); 
    $(document).ready(function() { 
     isDocumentReady = true; 
     if (isFontLoaded) { 
      init(); 
     } 
    }); 
    function init() { 
     // do something with $('#target').outerWidth() 
    } 
</script> 

免責聲明:我不能完全肯定這會工作。一旦樣式表被解析,但在其外部資源被下載之前,onload事件可能會觸發。也許你可以添加一個隱藏的<img src="fontFile.eot" />,並把你的onload處理器放在圖像上。

2

當DOM被加載時,「ready」事件觸發,這意味着可以安全地使用標記。

要等待所有資源被加載(CSS,圖像,外部JavaScript ...),你寧願使用加載事件。

$(window).load(function() { 
    ... 
}); 
1

我絕對,可重複地看到在IE9和IE10的同樣的問題。 jquery ready()調用會觸發,我的其中一個< div>不存在。如果我檢測到,然後在短暫的超時()後再次調用它可以正常工作。

我的解決辦法,只是爲了安全起見,爲兩方面:

  1. 附加一個< SCRIPT> window.fullyLoaded = TRUE; </SCRIPT>在文件的結尾然後檢查就緒()回調變量,

  2. 檢查$( '#lastElementInTheDocument')。長度> 0

是,我承認這些是討厭的黑客。但是,如果ready()未按預期工作,則需要某種解決方法!另外,「正確的」解決方案可能涉及在標題中設置$ .holdReady,並在文檔的末尾清除它。但是,當然,真正正確的解決方案是讓ready()工作。

+0

我想我也看到了這種行爲。也許解決方法是將document.ready命令放在頁面底部,這似乎是近來更常見的做法。我看到了這個問題,但我目前在標記中有我的document.ready命令。 – hairbo 2013-12-10 18:16:56

1

問題$(document).ready()太早發生有時可能會發生,因爲您已經錯誤地聲明瞭jQuery onReady函數。

如果有任何問題,請確保您的函數聲明完全像這樣:

$(document).ready(function() 
{ 
    // put your code here for what you want to do when the page loads. 
}); 

例如,如果您忘記了匿名函數部分,該代碼將繼續運行,但它會跑「出來的訂單「。

console.log('1'); 
$(document).ready() 
{ 
    console.log('3'); 
} 
console.log('2'); 

這將輸出

1 
3 
2 
相關問題