For front-end classmates loade, unload, DOMContentLoaded page loads such as trigger events must be in the process of contact, but if specifically asked the difference between individual events, I was not so clear answers come up. Having just seen the DOMContentLoaded event in the non-blocking script, scroll through the documentation to see each event in detail. As the saying goes, review the past and discover the new. Let’s look back

trigger

Let’s look at the timing of each event (refer to MDN)

DOMContentLoaded

Triggered when the initial HTML document is fully loaded and parsed, without waiting for styles, images, and subframes to finish. As an obvious contrast, the LOAD event fires only when a page is fully loaded. The place to use DOMContentLoaded is usually load, which is wrong. Tips: There are a number of generic and independent libraries that provide cross-browser methods to check if the DOM is ready for a ready event, and we’ll look at zepto’s implementation later

load

Triggered when a resource and its dependent resources finish loading. You can see here that you need to wait for the dependent resource to finish loading.

readystatechange

Document has a readyState property to describe the loading state of document. A change in the readyState will trigger the readyStatechange event.

  • loading

    The document is still loading

  • interactive

    The document is finished loading and parsed, but sub-resources such as images, styles, frames and so on are still loading

  • complete

    The document and child resources have finished loading, and this status indicates that the LOAD event is about to fire.

Therefore, we can also use this event to determine the loading status of the DOM. But not all objects go through these phases of readyState, and sometimes they do

beforeunload

The beforeUnload event is fired when a browser window, document, or its resources are about to unload. The document is still visible, and the event can be cancelled at this point. If the handler assigns a non-empty string to the returnValue property of the Event object, the browser pops up a dialog asking the user if they are sure they want to leave the current page (as shown in the following example). Some browsers display the returned string in a pop-up box, but others display only their custom information. When no value is assigned, the event does not respond. As of May 25, 2011, html5 states that calls to window.alert(), window.confirm(), and window.prompt() methods will be ignored.

unload

Raised after beforeUnload and PageHide events when a document or a child resource is about to be unloaded. The document will be in a specific state.

  • All resources still exist (images, iframes, etc.).
  • All resources are invisible to end users
  • Invalid interface interaction (window.open, alert, confirm, etc.).
  • Errors do not stop the process of uninstalling documents

Order of execution in page loading

From the above definition, we can get a clearer order.

  1. When a page is loaded, it must first issue a request to load resources, and no events are triggered until the load is complete.

  2. After the document is loaded and parsed, CSS and other resources are not loaded.

    ReadyState is ‘interactive’, indicating that the document is loaded and parsed, triggers readyStatechange, and then triggers DOMContentLoaded(as it does on most browsers). By the way, the script that has loaded with the defer tag starts executing in sequence.

  3. After loading sub-resources such as CSS and IMG

    The window.load event is raised

  4. Click close TAB or refresh, triggering beforeUnload and Unload events in sequence.

Maybe the concept looks a little boring, or look at the code is clearer. You can see what the following code outputs in turn.


      
<html>

<head>
    <title>Document load event</title>
    <script>
            document.addEventListener("DOMContentLoaded".function (event) {
                console.log("Initial DOM load and parse");
            });
            window.addEventListener("load".function (event) {
                console.log("All resources in window have loaded.");
            });
    
            document.onreadystatechange = function () {
                console.log(document.readyState)
                if (document.readyState === "complete") {
                    console.log('Initial DOM, load parsing done')}}window.addEventListener("beforeunload".function (event) {
                console.log('Closing soon')
                event.returnValue = "\o/";
            });
            window.addEventListener('unload'.function (event) {
                console.log('About to close 1');
            });
        </script>
    <link rel="stylesheet" href="./test.css">
</head>

<body>
    <div id="root">Dom events</div>
    <script src="./index.js"></script>
</body>

</html>
Copy the code

The output is as follows:

    interactive //(index):15The initial DOM loads and parses//(index):8
    complet//(index):15 The initial DOM is loaded and parsed//(index):17 
    windowAll resources are loaded//(index):11 
    // Click the close buttonImminent closure imminent closure2  
Copy the code

About ready

Jquery, Zepto and other libraries have a document ready method, to ensure that we operate after the initial DOM loading, the native DOM definition does not have this API, but the big players package the judgment process, to provide us with convenience. Given the previous example, let’s take a guess at how they did it.

  1. Ready corresponds to the state in which the initialized DOM has been loaded, so let’s look at what the case is.

    There are several states, complete, interactive, and DOMContentLoaded, which is also the initial DOM loaded, and of course the load event, which obviously won’t be used here, it’s a little late for the other states.

  2. Once the trigger condition is determined, the following implementation is easy to determine.

Using Zepto as an example, let’s look at the implementation:

Declare variables, not just interactive, because it was mentioned earlier that these states may not all occur
readyRE = /complete|loaded|interactive/

ready: function(callback){
      // need to check if document.body exists for IE as that browser reports
      // document ready when it hasn't yet created the body element
      if (readyRE.test(document.readyState) && document.body) callback($)
      else document.addEventListener('DOMContentLoaded'.function(){ callback($) }, false)
      return this
    } 
Copy the code

That concludes the introduction. For me, it helps to understand the concepts that were not so clear to me.

update

DOMContentLoaded is not triggered until CSS is loaded. This problem may exist, for example:

<div id="example-root">Test DOMContentLoaded with CSS</div>// Grab a piece of CSS<link rel="stylesheet" href="https://m.jb51.net/skin/mobile2017/css/common.css">
<script>
  document.addEventListener('DOMContentLoaded'.function () {
    alert('DOMContentLoaded trigger');
  });
</script>
Copy the code

At this point, you can see that the CSS is actually loaded when triggered.But before you jump to conclusions, change the order of the code:

<div id="example-root">Test DOMContentLoaded with CSS</div>
<script>
  document.addEventListener('DOMContentLoaded'.function () {
    alert('DOMContentLoaded trigger');
  });
</script>// Grab a piece of CSS<link rel="stylesheet" href="https://m.jb51.net/skin/mobile2017/css/common.css">
Copy the code

The CSS is still pending when DOMContentLoaded is triggeredIf you wait for the CSS to complete, it is obvious that the CSS should be loaded at this point.

conclusion

The DOMContentLoaded trigger does not wait for the CSS to finish loading. The phenomenon mentioned above is not the problem of the timing of DOMContentLoaded, but the problem of js execution order. When js listens for events, the CSS is already loaded, so it gives the illusion.