• 基于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);
            }
        }
    }());

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

  • 相关阅读:
    2018个人面试记录
    如何用纯代码实现图片CSS3
    JS数组删除
    JS数组去重
    HTML--使用提交按钮,提交数据
    HTML--使用下拉列表框进行多选
    HTML--使用下拉列表框,节省空间
    HTML--使用单选框、复选框,让用户选择
    HTML--文本域,支持多行文本输入
    HTML--文本输入框、密码输入框
  • 原文地址:https://www.cnblogs.com/timmer/p/10185006.html
Copyright © 2020-2023  润新知