¿Cómo puedo retrasar document.ready hasta que se establezca una variable?

Estoy haciendo pruebas de QUnit en un IFRAME y tengo una función de JavaScript recursiva que carga todos los scripts de la página principal en el IFRAME antes de iniciar QUnit. Esto funciona muy bien. Mi problema es que algunos de nuestros scripts usan document.ready para hacer que las cosas comiencen.

Algo como:

$(document).ready(function () {
    // blah
});

para hacer su trabajo. Preferiría no cambiar el código de producción solo para tener en cuenta las pruebas y no quiero que estos scripts de producción piensen que el documento IFRAME está "listo" hasta que se carguen todos los scripts.

¿Cómo puedo retrasar "document.ready"?

Aquí está mi pseudocódigo para darle un ejemplo para trabajar:

scripts[0] = "/foo/bar.js";
scripts[1] = "/blah/blah.js";

function RecursiveScriptStart(){
    // I want to set document.ready = false right here!
    if(scripts.length == 0) {
        QUnitStart();
        return;
    }
    RecursiveScriptLoader(0, scripts);
}

function RecursiveScriptLoader(currentScriptID, scripts) {
    $.getScript(scripts[currentScriptID], function () {
        if (currentScriptID == (scripts.length - 1)) {
            QUnitStart();
        }
        else {
            RecursiveScriptLoader(currentScriptID + 1, scripts);
        }
    });
}


function QUnitStart() {
        // I want to set document.ready = true right here!
        QUnit.stop();
        QUnit.start();
}

El código real es similar, pero involucra un selector de jquery que llena la matriz "scripts[]"con propiedades de etiqueta JavaScript" src ".

¡Gracias!

preguntado el 16 de mayo de 11 a las 20:05

Este patrón de La pregunta puede ser útil. -

5 Respuestas

Si está usando jQuery 1.6+, puede usar holdReady. Solo configurar $.holdReady(true) en la parte superior de su guión y luego al principio de QUnitStart conjunto $.holdReady(false).

Respondido 01 Oct 12, 18:10

@htellez sin jQuery no tendrías un $(document).ready() block, por lo que para responder esa pregunta tendríamos que conocer más detalles sobre lo que estás usando en su lugar. Quizás sea mejor hacer una pregunta separada en lugar de un comentario a esta. - mVChr

Si usa jQuery 1.6 o superior, puede usar holdReady para retrasar el disparo del evento listo.

Para 1.4.3 o superior, puede usar la propiedad $ .readyWait para retrasar el evento listo, Demo aquí (no es mi código)

si está interesado en averiguar cómo jquery maneja la búsqueda de eventos listos para la línea

jQuery( document ).trigger( "ready" ).unbind( "ready" );

en su copia de desarrollador de jquery.js

contestado el 19 de mayo de 11 a las 00:05

Este código funcionó para mí; Invocar $(window).load() dentro $(document).ready()

$(document).ready(function() {
    $(window).load(function() {
        // this code will run after all other $(document).ready() scripts
        // have completely finished, AND all page elements are fully loaded.
    });
});

Este método preservaría el orden de ejecución en todos los casos asegurándose de que su último código de ejecución no se pase a $(window).load() hasta que todo $(document).ready() Los guiones se han completado.

Respondido 10 ago 16, 23:08

Solo para completar donde otros lo dejaron, puede usar este orden de carga en su test.html

<script src="jquery.js"></script>
<script src="qunit.js"></script>
<script>$.holdReady(true);</script>
<script src="theThingIwantToTest.js"></script>
<script src="theTestScript.js"></script>

Respondido 03 Oct 12, 19:10

<html lang="en">
    <head>
        <meta charset="utf-8">
        <script type="text/javascript">
            window.setInterval(function() {
                console.log(document.getElementById('waitForMe'));
            }, 500);
        </script>
    </head>
    <body>
        Before
        <script type="text/javascript" src="/php-with-sleep.php"></script>
        After
        <div id="waitForMe"></div>
    </body>
</html>

Prueba extendida, he probado el complemento domReady de RequireJs

<html lang="en">
    <head>
        <meta charset="utf-8">
        <script type="text/javascript" src="/vendor/require/require.js"></script>
        <script type="text/javascript">
            window.setInterval(function() {
                console.log(document.getElementById('waitForMe'));
            }, 500);

            require.config({
                baseUrl: '/',
                paths: {
                    domReady: 'vendor/require/plugin/dom-ready',
                    jQuery: 'vendor/jquery'

                },
                shim: {
                    async: {
                        exports: 'async'
                    },
                    jQuery: {
                        exports: 'jQuery'
                    }
                }
            });

            require(['domReady', 'jQuery'], function(domReady, $) {
                console.log('jQuery loaded');
                $(function() {
                    console.log('jQuery dom ready');
                });

                domReady(function() {
                    console.log('domReady requireJs plugin, callback');
                })
            });

            require(['domReady!', 'jQuery'], function(domReady, $) {
                console.log('domReady! (no callback)');
            });

            require(['domReady', 'jQuery'], function(domReady, $) {
                console.log('domReady plugin loaded');
            });
        </script>
    </head>
    <body>
        Before
        <script type="text/javascript" src="/php-with-sleep.php"></script>
        After
        <div id="waitForMe"></div>
    </body>
</html>

Respondido 13 Feb 14, 18:02

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.