简体   繁体   English

还有比$(document).ready()更可靠的东西吗?

[英]Is there anything more reliable than $(document).ready()?

I have a utility that draws a simple arc, either using SVG or, as a fallback, Canvas. 我有一个实用程序绘制一个简单的弧,使用SVG或作为后备,Canvas。 (An early version can be found in my Raphael Arcs Project on my website. (早期版本可以在我的网站上的Raphael Arcs项目中找到。

To accomodate a mobile solution, I recently added code to monitor the size of the container and, if it changes, to re-draw the image to fit the newly sized container. 为了适应移动解决方案,我最近添加了代码来监控容器的大小,如果更改,则重新绘制图像以适应新容量的容器。 This addition uses only the size of the containing DIV; 此添加仅使用包含DIV的大小; the code adds either a SVG or Canvas object to the DIV. 代码将一个SVG或Canvas对象添加到DIV。

Repeatedly reloading the page, however, sometimes the DIV layout isn't ready even when $(document).ready says it is. 然而,反复重新加载页面,有时DIV布局还没有准备好,即使$(document).ready说它是。 This seems to be most prevalent under Chrome; 这似乎在Chrome下最为普遍; I've seen it only once with Opera and never with Firefox 3.6. 我在Opera中只见过一次,从未在Firefox 3.6中看过它。 The height and width of the containing DIV come back as zero. 包含DIV的高度和宽度返回为零。

If you load the link above in Chrome and hit reload, every tenth hit or so the Canvas demo will show a similar flaw: it will be sized width: 100% of viewport, height: 300px, and the demo will not draw correctly. 如果您在Chrome中加载上面的链接并点击重新加载,每隔十分钟左右,Canvas演示将显示一个类似的缺陷:它的大小将是宽度:视口的100%,高度:300px,并且演示将无法正确绘制。

I've looked through the jQuery documentation and it seems to insist that $(document).ready() ought to be enough. 我查看了jQuery文档,似乎坚持认为$(document).ready()应该足够了。 I'd rather not have 12% of my users experience a browser-related failure. 我宁愿没有12%的用户遇到与浏览器相关的故障。 Other than writing my own layout probe (a spinning Timeout asking, over and over, "is the container sized yet?"), is there a common technique or library to assure that not only is the DOM loaded but the layout manager has settled? 除了编写我自己的布局探测器(一个旋转的Timeout一遍又一遍地问,“容器大小了吗?”),是否有一个通用的技术或库来确保不仅加载了DOM而且布局管理器已经解决了?

[EDIT] [编辑]

I've ended up doing something like this (code is Coffeescript): 我最终做了这样的事情(代码是Coffeescript):

$(document).ready ->
    $('.wrapper').each ->
        demo = =>
            c = new CanvasArc $('.canvas_demo', this)
            c.sweep(1.0)
            r = new RaphaelArc $('.raphael_demo', this)
            r.sweep(1.0)
        scan = =>
            if $('.canvas_demo', this).height()
                demo()
            else
                setTimeout(scan, 100)
        scan()

I really shouldn't have to do that. 我真的不应该这样做。

You are right that you shouldn't have to work around this. 你是对的,你不应该解决这个问题。 The answer is hidden in the .ready() section : 答案隐藏在.ready()部分中

When using scripts that rely on the value of CSS style properties, it's important to reference external stylesheets or embed style elements before referencing the scripts. 使用依赖于CSS样式属性值的脚本时,在引用脚本之前引用外部样式表或嵌入样式元素很重要。

So all you need to do is include your CSS first and then your scripts. 所以你需要做的就是首先包括你的CSS然后再包括你的脚本。 This way, your ready-event handler isn't even being set until after the CSS has been loaded. 这样,直到加载CSS之后才会设置就绪事件处理程序。

The whole point of $(document).ready is that it fires as soon as the DOM is ready for manipulation, without having to wait for all the images to download. $(document).ready是,只要DOM准备好进行操作就会触发,而不必等待所有图像下载。 If you need images to have downloaded, you should attach to the regular onload event. 如果您需要下载图像,则应附加到常规onload事件。 If you're adding images dynamically, you may be able to attach to the onload event of an Image object and do some stuff then. 如果要动态添加图像,则可以附加到Image对象的onload事件,然后执行一些操作。

ready is an event that signifies that the DOM is ready for scripting—that is, all elements exist with their basic properties and you can add/remove elements, etc.—but not that all the elements have rendered. ready是一个表示DOM已准备好编写脚本的事件 - 也就是说,所有元素都存在其基本属性,您可以添加/删除元素等,但不是所有元素都已呈现。 Use window.onload ( load in jQuery) if you want to be sure that all "loaded assets" have completely finished loading all content, including images and possibly other embedded content that takes time to load. 使用window.onloadload如果你想确保所有的“装资产”已经完全加载完所有内容,包括图像和其他可能嵌入的内容,需要时间来加载jQuery中)。

jQuery's ready page says: jQuery的准备页面说:

In cases where code relies on loaded assets, the code should be placed in a handler for the load event instead. 在代码依赖于加载的资产的情况下,代码应该放在load事件的处理程序中。

Are any of the contents of the div that you are looking at "loaded assets"? 您正在查看“加载资产”的div任何内容吗? If so, then their loading can change the size of the div after the ready event. 如果是这样,那么它们的加载可以在ready事件之后改变div的大小。 Theoretically, you then should be able to use asset.load to respond as soon as a particular loaded asset has finished downloading. 从理论上讲,您应该能够在特定的已加载资产下载完成后立即使用asset.load进行响应。 Use document.ready to wire up this event. 使用document.ready连接此事件。

你不应该依赖脚本来调整div的大小,而是让他通过CSS调整大小,宽度为百分比,这样就可以在文档准备就绪时调整它的大小。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM