2012-02-03 135 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 
相关问题