$(document).ready()过早发射

时间:2012-02-03 20:15:36

标签: javascript jquery dom

所以,我需要知道带有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的宽度,问题是在警报之前执行的代码提供的输出与之后的输出不同,可能是因为字体未完全加载并且正在测量div与默认字体。

它可以像我期望的那样在谷歌浏览器中运行,但它不适用于IE和Firefox。

7 个答案:

答案 0 :(得分:69)

如果您依赖外部内容(例如图片,字体),则需要使用window.load事件

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

this article

中描述了这些事件的行为
  

有[a]就绪状态,但称为DOM-ready。这是浏览器实际构建页面的时候,但仍然可能需要抓取一些图像或flash文件。

编辑:changed syntax to also work with jQuery 3.0,如Alex H所述

答案 1 :(得分:12)

引用OP:

  

“据我了解,文档完成时会触发$(document).ready()函数,”

当DOM(“文档对象模型”)完全加载并准备好进行操作时,

$(document).ready()将触发。 DOM与“文档”不同。

W3C - DOM Frequently Asked Questions

您可以尝试使用$(window).load()功能......

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

它将等待所有页面的资源(如图像和字体等)在开始之前完全加载。

答案 2 :(得分:5)

一旦DOM完成,jQuery .ready()函数就会触发。这并不意味着当时已加载所有资产(如图像,CSS等),因此元素的大小可能会发生变化。

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

答案 3 :(得分:4)

加载DOM时会激活“ready”事件,这意味着可以安全地使用标记。

要等待加载所有资源(css,图像,外部javascript ......),您宁愿使用加载事件。

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

答案 4 :(得分:2)

您可以使用$(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> 

免责声明:我不完全确定这会有效。解析样式表后,<link> onload事件可能会触发,但在下载外部资源之前。也许你可以添加一个隐藏的<img src="fontFile.eot" />并将你的onload处理程序放在图像上。

答案 5 :(得分:1)

我绝对可以在IE9和IE10中重复看到同样的问题。 jquery ready()调用触发,我的&lt; div&gt;之一不存在。如果我检测到它然后在短暂的超时后再次调用()它可以正常工作。

为了安全起见,我的解决方案有两方面:

  1. 附加&lt; script&gt; window.fullyLoaded = true;&lt; / script&gt;在文档的末尾,然后在ready()回调中检查该变量,AND

  2. 检查$('#lastElementInTheDocument')。length&gt; 0

  3. 是的,我知道这些是讨厌的黑客。但是,当ready()没有按预期工作时,需要进行某种解决方法!

    顺便说一句,“正确”解决方案可能涉及在标题中设置$ .holdReady,并在文档末尾清除它。但是,当然,真正正确的解决方案是让ready()工作。

答案 6 :(得分: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