Recibir una notificación cuando la página DOM se haya cargado (pero antes de window.onload)

StackOverflow https://stackoverflow.com/questions/65434

  •  09-06-2019
  •  | 
  •  

Pregunta

Sé que hay algunas formas de recibir notificaciones cuando el cuerpo de la página se haya cargado (antes de que se carguen todas las imágenes y recursos de terceros, lo que activa el ventana.onload evento), pero es diferente para cada navegador.

¿Existe una forma definitiva de hacer esto en todos los navegadores?

Hasta ahora sé de:

  • Contenido DOM cargado :En Mozilla, Opera 9 y WebKits más recientes.Esto implica agregar un oyente al evento:

    document.addEventListener( "DOMContentLoaded", [función de inicio], falso);

  • Guión diferido:En IE, puede emitir una etiqueta SCRIPT con un atributo @defer, que de manera confiable solo se cargará después del cierre de la etiqueta BODY.

  • Votación:En otros navegadores, puede seguir realizando encuestas, pero ¿existe algo estándar para realizar encuestas o es necesario hacer cosas diferentes en cada navegador?

Me gustaría poder prescindir del uso de document.write o archivos externos.

Esto se puede hacer simplemente mediante jQuery:

$(document).ready(function() { ... })

pero estoy escribiendo una biblioteca JS y no puedo contar con que jQuery esté siempre ahí.

¿Fue útil?

Solución

No existe un método entre navegadores para comprobar cuándo el DOM está listo; es por eso que existen bibliotecas como jQuery, para abstraer pequeñas y desagradables incompatibilidades.

Mozilla, Opera y WebKit moderno admiten la DOMContentLoaded evento.IE y Safari necesitan trucos extraños, como desplazarse por la ventana o consultar hojas de estilo.Los detalles sangrientos están contenidos en jQuery. bindReady() función.

Otros consejos

Encontré esta página, que muestra una solución compacta e independiente.Parece funcionar en todos los navegadores y tiene una explicación sobre cómo:

http://www.kryogenix.org/days/2007/09/26/shortloaded

YUI utiliza tres pruebas para hacer esto:para Firefox y WebKit reciente hay un evento DOMContentLoaded que se activa.Para Safari más antiguo, el documento.readyState se observó hasta que se "cargó" o se "completó".Para IE, se crea una etiqueta HTML <P> y se llama al método "doScroll()", que debería generar un error si el DOM no está listo.La fuente para YAHOO.util.Evento muestra el código específico de YUI.Busque "doScroll" en Event.js.

Usar una biblioteca como jQuery le ahorrará innumerables horas de inconsistencias en los navegadores.

En este caso con jQuery puedes simplemente

$(document).ready ( function () {
    //your code here
});

Si tiene curiosidad, puede echar un vistazo a la fuente para ver cómo se hace, pero hoy en día no creo que nadie deba reinventar esta rueda cuando el escritor de la biblioteca ha hecho todo el doloroso trabajo por usted.

Simplemente tome el fragmento de código relevante de jQuery, John Resig ya ha cubierto la mayoría de los conceptos básicos sobre este tema en jQuery.

¿Por qué no esto?

<body>  
  <!-- various content -->  
  <script type="text/javascript">  
  <!--  
    myInit();  
  -->
  </script>  
</body>  

Si entiendo las cosas correctamente, myInit se ejecutará tan pronto como el navegador llegue a la página, que es lo último en el cuerpo.

La sofisticada solución de navegador cruzado que está buscando... no existe...(imagínese el sonido de una gran multitud diciendo 'aahhhh....').

DomContenidoCargado es simplemente tu mejor oportunidad.Todavía necesitas el polling técnica para IE-oldies.

  1. Intente utilizar addEventListener;
  2. Si no está disponible (es decir, obviamente), busque marcos;
  3. Si no es un marco, desplácese hasta que no se genere ningún error (encuesta);
  4. Si es un marco, utilice el evento IE document.onreadystatechange;
  5. Para otros navegadores que no sean compatibles, utilice el evento document.onload antiguo.

Encontré el siguiente ejemplo de código en javascript.info que puedes usar para cubrir todos los navegadores:

function bindReady(handler){

    var called = false

    function ready() { 
        if (called) return
        called = true
        handler()
    }

    if ( document.addEventListener ) { // native event
        document.addEventListener( "DOMContentLoaded", ready, false )
    } else if ( document.attachEvent ) {  // IE

        try {
            var isFrame = window.frameElement != null
        } catch(e) {}

        // IE, the document is not inside a frame
        if ( document.documentElement.doScroll && !isFrame ) {
            function tryScroll(){
                if (called) return
                try {
                    document.documentElement.doScroll("left")
                    ready()
                } catch(e) {
                    setTimeout(tryScroll, 10)
                }
            }
            tryScroll()
        }

        // IE, the document is inside a frame
        document.attachEvent("onreadystatechange", function(){
            if ( document.readyState === "complete" ) {
                ready()
            }
        })
    }

    // Old browsers
    if (window.addEventListener)
        window.addEventListener('load', ready, false)
    else if (window.attachEvent)
        window.attachEvent('onload', ready)
    else {
        var fn = window.onload // very old browser, copy old onload
        window.onload = function() { // replace by new onload and call the old one
            fn && fn()
            ready()
        }
    }
}

Esto funciona bastante bien:

setTimeout(MyInitFunction, 0);

Usar setTimeout puede funcionar bastante bien, aunque el momento de su ejecución depende del navegador.Si pasa cero como tiempo de espera, el navegador se ejecutará cuando todo esté "resuelto".

Lo bueno de esto es que puedes tener muchos de ellos y no tienes que preocuparte por encadenar eventos onLoad.

setTimeout(myFunction, 0);
setTimeout(anotherFunction, 0);
setTimeout(function(){ doSomething ...}, 0);

etc.

Todos se ejecutarán cuando el documento haya terminado de cargarse, o si configura uno después de cargar el documento, se ejecutarán después de que el script haya terminado de ejecutarse.

El orden en que se ejecutan no está determinado y puede cambiar entre navegadores.Así que no puedes contar con myFunction siendo ejecutado antes anotherFunction Por ejemplo.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top