简体   繁体   中英

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. (An early version can be found in my Raphael Arcs Project on my website.

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; the code adds either a SVG or Canvas object to the DIV.

Repeatedly reloading the page, however, sometimes the DIV layout isn't ready even when $(document).ready says it is. This seems to be most prevalent under Chrome; I've seen it only once with Opera and never with Firefox 3.6. The height and width of the containing DIV come back as zero.

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.

I've looked through the jQuery documentation and it seems to insist that $(document).ready() ought to be enough. I'd rather not have 12% of my users experience a browser-related failure. 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?

[EDIT]

I've ended up doing something like this (code is 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 :

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.

So all you need to do is include your CSS first and then your scripts. This way, your ready-event handler isn't even being set until after the CSS has been loaded.

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. If you need images to have downloaded, you should attach to the regular onload event. 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.

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. 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.

jQuery's ready page says:

In cases where code relies on loaded assets, the code should be placed in a handler for the load event instead.

Are any of the contents of the div that you are looking at "loaded assets"? If so, then their loading can change the size of the div after the ready event. Theoretically, you then should be able to use asset.load to respond as soon as a particular loaded asset has finished downloading. Use document.ready to wire up this event.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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