zoukankan      html  css  js  c++  java
  • 基于DOMContentLoaded实现文档加载完成后执行的方法

    我们有时可能需要一些在页面加载完成之后执行的方法,其实js原生就提供了onload方法,所以我们最简单的办法就是直接给onload赋值一个函数,在页面加载完成之后就会自动执行

    widnow.onload = function(e) {
      // do some things  
    }

    或者我们也可以使用addEventListener,来监听多个load事件,此处我们先暂时不考虑低版本的ie

    document.addEventListener("load", function(e) {
       // do some things 
    }, false);

    这个时候,我们考虑到,明显jq的ready方法更好使用,而且简单很多,所以我们也可以通过切片编程的方法来实现一个onload方法

    // after切片,可以在方法之后增加after,顺序执行
    Function.prototype.after = function(func) {
        var _self = this;
        // 返回一个新的可执行方法
        return function() {
            var ret = _self.apply(this, arguments);
            // 当上一个方法返回false,则不会执行下一个after
        if(ret === false) {
            return false;
        }
        func.apply(this, arguments);
        return ret;
        }
    }
    
    $ = function(func) {
        window.onload = (window.onload || function() {}).after(func);
    }
    
    // 使用
    $(function() {});    $(function() {});

    当然,感觉可能实现还不如无限次的调用addEventListener,虽然这个方法可以保证执行顺序

    而实际上,你在使用该方法的时候,会发现这个方法始终会在jq的ready之后执行,是因为jq的ready实现,是监听了DOMContentLoaded,这个事件是在文档加载完成之后就会触发,而不必等待所有的资源包括异步资源加载完成。所以我们最后的实现可以这样

    var $ = (function() {
        var funcs = [];    // 保存所有需要执行的方法
        var ready = false;    // 页面准备完毕之后,修改为true
    
        // 当文档处理完毕,调用事件处理程序
        function handler(e) {
            // 如果执行过了,直接返回
            if(ready) {
                return;
            }
    
            // 如果发生过readysyayechange事件,但是状态不为complete,那么文档没有准备好
            if(e.type === "readystatechange" && document.readyState !== "complete") {
                return;
            }
    
            // 运行所有注册函数
            for(var i = 0; i < funcs.length; i++) {
                funcs[i].call(document);
            }
    
            // 设置ready为true,并移除所有方法
            ready = true;
            funcs = null;
        }
    
        // 为接收到的任何事件注册处理程序
        if(document.addEventListener) {
            document.addEventListener("DOMContentLoaded", handler, false);
            document.addEventListener("readystatechange", handler, false);
            document.addEventListener("load", handler, false);
        } else if(document.attachEvent) {    // 处理ie兼容
            document.attachEvent("onreadystatechange", handler);
            document.attachEvent("onload", handler);
        }
    
        // 返回__whenReady函数
        return function __whenReady(f) {
            if(ready) {
                f.call(document);
            } else {
                funcs.push(f);
            }
        }
    }());

    核心就是在判断几个加载事件执行的时候,文档是否准备好,如果没有准备好,则将需要执行的函数按照顺序缓存起来,然后在监听到文档准备好之后依次执行。

  • 相关阅读:
    el-table背景色透明
    判断数组对象里的属性值是否重复
    :Duplicate keys detected: 'xxx'. This may cause an update error.
    钉钉微应用附件下载方案
    探索JS引擎工作原理
    js深度优先遍历和广度优先遍历实现
    微前端qiankun从搭建到部署的实践
    浏览器与Node的事件循环(Event Loop)有何区别?
    JS
    微信小程序预览Word文档
  • 原文地址:https://www.cnblogs.com/timmer/p/10185006.html
Copyright © 2011-2022 走看看