los DOMContentLoaded
El evento se activa cuando el documento HTML inicial se ha cargado y analizado por completo, sin esperar a que las hojas de estilo, las imágenes y los subcuadros terminen de cargarse.
Burbujas | sí |
---|---|
Cancelable | Sí (aunque se especifica como un evento simple que no se puede cancelar) |
Interfaz | Event |
Propiedad del controlador de eventos | Ninguno |
Un evento diferente load
, debe usarse solo para detectar una página completamente cargada. Es un error común usar load
dónde DOMContentLoaded
sería más apropiado.
JavaScript síncrono detiene el análisis del DOM. Si desea que el DOM se analice lo más rápido posible después de que el usuario haya solicitado la página, puede hacer que su JavaScript asincrónico y optimizar la carga de hojas de estilo. Si se cargan como de costumbre, las hojas de estilo ralentizan el análisis de DOM ya que se cargan en paralelo, “robando” el tráfico del documento HTML principal.
Polyfill
El siguiente código transfiere la funcionalidad del DOMContentLoaded
evento todo el camino de regreso a IE6 +, con un respaldo a window.onload
que funciona en todas partes.
// Usage: DOMContentLoaded(function(e) console.log(e); /* your code here */);functionDOMContentLoaded()"use strict";var ael ='addEventListener', rel ='removeEventListener', aev ='attachEvent', dev ='detachEvent';var alreadyRun =false, funcs = arguments;// for use in the idempotent function `ready()`, defined later.functionmicrotime()return+newDate()// new Date().valueOf();/* The vast majority of browsers currently in use now support both addEventListener and DOMContentLoaded. However, 2% is still a significant portion of the web, and graceful degradation is still the best design approach. `document.readyState === 'complete'` is functionally equivalent to `window.onload`. The events fire within a few tenths of a second, and reported correctly in every browser that was tested, including IE6. But IE6 to 10 did not correctly return the other readyState values as per the spec: In IE6-10, readyState was sometimes 'interactive', even when the DOM wasn't accessible, so it's safe to assume that listening to the `onreadystatechange` event in legacy browsers is unstable. Should readyState be undefined, accessing undefined properties of a defined object (document) will not throw. The following statement checks for IE < 11 via conditional compilation. `@_jscript_version` is a special String variable defined only in IE conditional comments, which themselves only appear as regular comments to other browsers. Browsers not named IE interpret the following code as `Number( new Function("")() )` => `Number(undefined)` => `NaN`. `NaN` is neither >, <, nor = to any other value. Values: IE5: 5?, IE5.5: 5.5?, IE6/7: 5.6/5.7, IE8: 5.8, IE9: 9, IE10: 10, (IE11 older doc mode*): 11, IE11 / NOT IE: undefined */var jscript_version =Number(newFunction("/*@cc_on return @_jscript_version; @*/")());// check if the DOM has already loaded// If it has, send null as the readyTime, since we don't know when the DOM became ready.if(document.readyState ==='complete')ready(null);return;// execute ready()// For IE<9 poll document.documentElement.doScroll(), no further actions are needed.if(jscript_version <9)doIEScrollCheck();return;// ael: addEventListener, rel: removeEventListener, aev: attachEvent, dev: detachEventif(document[ael]) document[ael]("DOMContentLoaded", ready,false);// fallback to the universal load event in case DOMContentLoaded isn't supported. window[ael]("load", ready,false);elseif(aev in window) window[aev]('onload', ready);// Old Opera has a default of window.attachEvent being falsy, so we use the in operator instead.// https://dev.opera.com/blog/window-event-attachevent-detachevent-script-onreadystatechange/else// fallback to window.onload that will always work.addOnload(ready);// addOnload: Allows us to preserve any original `window.onload` handlers,// in ancient (prehistoric?) browsers where this is even necessary, while providing the// option to chain onloads, and dequeue them later.functionaddOnload(fn)var prev = window.onload;// old `window.onload`, which could be set by this function, or elsewhere.// Here we add a function queue list to allow for dequeueing.// Should we have to use window.onload, `addOnload.queue` is the queue of functions// that we will run when the DOM is ready.if(typeof addOnload.queue !=='object')// allow loose comparison of arrays addOnload.queue =[];if(typeof prev ==='function') addOnload.queue.push( prev );// add the previously defined event handler, if any.if(typeof fn ==='function') addOnload.queue.push(fn)// add the new function window.onload=function()// iterate through the queued functionsfor(var i =0; i < addOnload.queue.length; i++) addOnload.queue[i]();// dequeueOnload: remove a queued `addOnload` function from the chain.functiondequeueOnload(fn, all)// Sort backwards through the queued functions in `addOnload.queue` (if it's defined)// until we find `fn`, and then remove `fn` from its place in the array.if(typeof addOnload.queue ==='object')// arrayfor(var i = addOnload.queue.length-1; i >=0; i--)// iterate backwardsif(fn === addOnload.queue[i]) addOnload.queue.splice(i,1);if(!all)break// ready: idempotent event handler functionfunctionready(ev)if(alreadyRun)return alreadyRun =true;// This time is when the DOM has loaded, or, if all else fails,// when it was actually possible to inference that the DOM has loaded via a 'load' event.var readyTime =microtime();detach();// detach any event handlers// run the functions (`funcs` is arguments of DOMContentLoaded)for(var i=0; i < funcs.length; i++)var func = funcs[i];if(typeof func ==='function')// force set `this` to `document`, for consistency.func.call(document,'readyTime':(ev ===null?null: readyTime),'funcExecuteTime':microtime(),'currentFunction': func );// detach: detach all the currently registered events.functiondetach()if(document[rel]) document[rel]("DOMContentLoaded", ready); window[rel]("load", ready);elseif(dev in window) window[dev]("onload", ready);elsedequeueOnload(ready);// doIEScrollCheck: poll document.documentElement.doScroll until it no longer throws.functiondoIEScrollCheck()// for use in IE < 9 only.if( window.frameElement )/* We're in an `iframe` or similar. The `document.documentElement.doScroll` technique does not work if we're not at the top-level (parent document). Attach to onload if we're in an try window.attachEvent("onload", ready);catch(e)return;// if we get here, we're not in an `iframe`.try// when this statement no longer throws, the DOM is accessible in old IE document.documentElement.doScroll('left');catch(error)setTimeout(function()(document.readyState ==='complete')?ready():doIEScrollCheck();,50);return;ready();// Tested via BrowserStack.
Ejemplos de
Uso básico
document.addEventListener('DOMContentLoaded',(event)=> console.log('DOM fully loaded and parsed'););
Retrasar DOMContentLoaded
<script> document.addEventListener('DOMContentLoaded',(event)=> console.log('DOM fully loaded and parsed'););for(let i =0; i <1000000000; i++)// This synchronous script is going to delay parsing of the DOM,// so the DOMContentLoaded event is going to launch later.script>
Comprobando si la carga ya está completa
DOMContentLoaded
puede dispararse antes de que su script tenga la oportunidad de ejecutarse, por lo que es aconsejable verificar antes de agregar un oyente.
functiondoSomething() console.info('DOM loaded');if(document.readyState ==='loading')// Loading hasn't finished yet document.addEventListener('DOMContentLoaded', doSomething);else// `DOMContentLoaded` has already fireddoSomething();
Ejemplo vivo
HTML
<divclass="controls"><buttonid="reload"type="button">Reloadbutton>div><divclass="event-log"><label>Event log:label><textareareadonlyclass="event-log-contents"rows="8"cols="30">textarea>div>
JS
const log = document.querySelector('.event-log-contents');const reload = document.querySelector('#reload'); reload.addEventListener('click',()=> log.textContent =''; window.setTimeout(()=> window.location.reload(true);,200);); window.addEventListener('load',(event)=> log.textContent = log.textContent +'loadn';); document.addEventListener('readystatechange',(event)=> log.textContent = log.textContent +`readystate: $document.readyStaten`;); document.addEventListener('DOMContentLoaded',(event)=> log.textContent = log.textContent +`DOMContentLoadedn`;);
Resultado
Especificaciones
Especificación | Estado | Comentario |
---|---|---|
Estándar de vida HTML La definición de ‘DOMContentLoaded’ en esa especificación. |
Estándar de vida | |
HTML5 La definición de ‘DOMContentLoaded’ en esa especificación. |
Recomendación |
Compatibilidad del navegador
Escritorio | Móvil | |||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|
Cromo | Borde | Firefox | explorador de Internet | Ópera | Safari | WebView Android | Chrome Android | Firefox para Android | Opera Android | Safari en IOS | Internet de Samsung | |
DOMContentLoaded_event |
1 | 12 | 1 | 9 | 9 | 3.1 | 1 | 18 | 4 | 10.1 | 2 | 1.0 |
Ver también
- Eventos relacionados:
load
,readystatechange
,beforeunload
,unload
- Este evento en
Window
objetivos:DOMContentLoaded
Si conservas alguna desconfianza y disposición de reformar nuestro escrito puedes realizar una crítica y con gusto lo estudiaremos.