《JavaScript框架设计》——1.5 主流框架引入的机制——domReady

简介:

本节书摘来自异步社区《JavaScript框架设计》一书中的第1章,第1.5节,作者:司徒正美 更多章节内容可以访问云栖社区“异步社区”公众号查看。

1.5 主流框架引入的机制——domReady

domReady其实是一种名为“DOMContentLoaded”事件的别称,不过由于框架的需要,它与真正的DOMContentLoaded有一点区别。在许多旧的JavaScript书藉中,它们都会教导我们把JavaScript逻辑写在window.onload回调中,以防DOM树还没有建完就开始对节点进行操作,导致出错。而对于框架来说,越早介入对DOM的干涉就越好,如要进行什么特征侦测之类的。domReady还可以满足用户提前绑定事件的需求,因为有时页面图片等资源过多,window.onload就迟迟不能触发,这时若还没有绑定事件,用户点哪个按钮都没反应(除了跳转外)。因此主流框架都引入domReady机制,并且费了很大劲兼容所有浏览器,具体策略如下。

(1)对于支持DOMContentLoaded事件的使用DOMContentLoaded事件。

(2)旧版本IE使用Diego Perini发现的著名hack!

//by Diego Perini 2007.10.5
function IEContentLoaded(w, fn) {
    var d = w.document, done = false,
            init = function() {
        if (!done) {//只执行一次
            done = true;
            fn();
        }
    };
    (function() {
        try {//在DOM未建完之前调用元素doScroll抛出错误
            d.documentElement.doScroll('left');
        } catch (e) {//延迟再试
            setTimeout(arguments.callee, 50);
            return;
        }
        init();//没有错误则执行用户回调
    })();
    // 如果用户是在domReady之后绑定这个函数呢?立即执行它
    d.onreadystatechange = function() {
        if (d.readyState == 'complete') {
            d.onreadystatechange = null;
            init();
        }
    };
}

此外,IE还可以通过script defer hack进行判定。

//by Andrea Giammarchi 2006.9.24
document.write("<script id=__ie_onload defer src=//0><\/scr" + "ipt>");
script = document.getElementById("__ie_onload");
script.onreadystatechange = function() {//IE即使是死链也能触发事件
    if (this.readyState == "complete"){
        init(); // 指定了defer的script会在DOM树建完才触发
    };

不过有个问题是,如果我们的种子模块是动态加载的,在它插入DOM树时,DOM树已经建完呢?这该怎么触发我们的ready回调?jQuery给出的方案是,连onload也监听了,但如果连onload也没赶上,就判定document.readyState是否等于complete!这样完美了吧,可惜Firefox3.6之前没有这属性!看mass给出的方案。

var readyList = [];
mass.ready = function(fn) {
    if (readyList) {
        fn.push(fn);
    } else {
        fn();
    }
}
var readyFn, ready = W3C ? "DOMContentLoaded" : "readystatechange";
function fireReady() {
    for (var i = 0, fn; fn = readyList[i++]; ) {
        fn();
    }
    readyList = null;
    fireReady = $.noop; //惰性函数,防止IE9二次调用_checkDeps
}
function doScrollCheck() {
    try { //IE下通过doScrollCheck检测DOM树是否建完
        html.doScroll("left");
        fireReady();
    } catch (e) {
        setTimeout(doScrollCheck);
    }
}

//在Firefox3.6之前,不存在readyState属性

if (!DOC.readyState) {
    var readyState = DOC.readyState = DOC.body ? "complete" : "loading";
}
if (DOC.readyState === "complete") {
    fireReady(); //如果在domReady之外加载
} else {
    $.bind(DOC, ready, readyFn = function() {
        if (W3C || DOC.readyState === "complete") {
            fireReady();
            if (readyState) { //IE下不能改写DOC.readyState
                DOC.readyState = "complete";
            }
        }
    });
    if (html.doScroll) {
        try { //如果跨域会报错,那时肯定证明是存在两个窗口的
            if (self.eval === parent.eval) {
                doScrollCheck();
            }
        } catch (e) {
            doScrollCheck();
        }
    }
}
相关文章
|
7月前
|
JavaScript 前端开发 API
|
12月前
|
Web App开发 JavaScript 前端开发
深入浅出Node.js后端框架
【10月更文挑战第34天】在数字化时代,后端开发如同一座桥梁,连接着用户界面与数据处理的两端。本文将通过Node.js这一轻量级、高效的平台,带领读者领略后端框架的魅力。我们将从基础概念出发,逐步深入到实战应用,最后探讨如何通过代码示例来巩固学习成果,使读者能够在理论与实践之间架起自己的桥梁。
|
11月前
|
数据采集 人工智能 自然语言处理
Midscene.js:AI 驱动的 UI 自动化测试框架,支持自然语言交互,生成可视化报告
Midscene.js 是一款基于 AI 技术的 UI 自动化测试框架,通过自然语言交互简化测试流程,支持动作执行、数据查询和页面断言,提供可视化报告,适用于多种应用场景。
2732 1
Midscene.js:AI 驱动的 UI 自动化测试框架,支持自然语言交互,生成可视化报告
|
12月前
|
缓存 监控 JavaScript
Vue.js 框架下的性能优化策略与实践
Vue.js 框架下的性能优化策略与实践
|
12月前
|
Web App开发 JSON JavaScript
Node.js 中的中间件机制与 Express 应用
Node.js 中的中间件机制与 Express 应用
|
12月前
|
缓存 负载均衡 JavaScript
构建高效后端服务:Node.js与Express框架实践
在数字化时代的浪潮中,后端服务的重要性不言而喻。本文将通过深入浅出的方式介绍如何利用Node.js及其强大的Express框架来搭建一个高效的后端服务。我们将从零开始,逐步深入,不仅涉及基础的代码编写,更会探讨如何优化性能和处理高并发场景。无论你是后端新手还是希望提高现有技能的开发者,这篇文章都将为你提供宝贵的知识和启示。
|
12月前
|
开发框架 JavaScript 前端开发
TypeScript 是一种静态类型的编程语言,它扩展了 JavaScript,为 Web 开发带来了强大的类型系统、组件化开发支持、与主流框架的无缝集成、大型项目管理能力和提升开发体验等多方面优势
TypeScript 是一种静态类型的编程语言,它扩展了 JavaScript,为 Web 开发带来了强大的类型系统、组件化开发支持、与主流框架的无缝集成、大型项目管理能力和提升开发体验等多方面优势。通过明确的类型定义,TypeScript 能够在编码阶段发现潜在错误,提高代码质量;支持组件的清晰定义与复用,增强代码的可维护性;与 React、Vue 等框架结合,提供更佳的开发体验;适用于大型项目,优化代码结构和性能。随着 Web 技术的发展,TypeScript 的应用前景广阔,将继续引领 Web 开发的新趋势。
276 2
|
12月前
|
JavaScript 安全 中间件
深入浅出Node.js中间件机制
【10月更文挑战第36天】在探索Node.js的奥秘之旅中,中间件的概念如同魔法一般,它让复杂的请求处理变得优雅而高效。本文将带你领略这一机制的魅力,从概念到实践,一步步揭示如何利用中间件简化和增强你的应用。
|
12月前
|
JavaScript 前端开发 开发者
JavaScript框架React vs. Vue:一场性能与易用性的较量
JavaScript框架React vs. Vue:一场性能与易用性的较量
299 0
|
Web App开发 JavaScript 前端开发
构建高效后端服务:Node.js与Express框架的实践
【10月更文挑战第33天】在数字化时代的浪潮中,后端服务的效率和可靠性成为企业竞争的关键。本文将深入探讨如何利用Node.js和Express框架构建高效且易于维护的后端服务。通过实践案例和代码示例,我们将揭示这一组合如何简化开发流程、优化性能,并提升用户体验。无论你是初学者还是有经验的开发者,这篇文章都将为你提供宝贵的见解和实用技巧。