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

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

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

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

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

//http://javascript.nwbox.com/IEContentLoaded/
//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进行判定。

//http://webreflection.blogspot.com/search?q=onContent
//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属性
//http://www.cnblogs.com/rubylouvre/archive/2012/12/18/2822912.html
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();
        }
    }
}

时间: 2024-08-04 11:08:20

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

WinForm企业应用框架设计【三】框架窗体设计;动态创建菜单;

要不是我的朋友乔乔==乔不死跟我聊到领域驱动设计~ 我也不会发现第一篇中关于"充血实体"的错误说法(至少~我写文章的时候~内心的想法是错的~) 我个人不是很喜欢领域驱动设计~感觉这种思路(我们暂且叫它思路~虽然它有一些既有的原则和模式) 重点要求架构师深入到业务领域中去~ 但是在国内往往很难真正的与领域专家做深入交流~ 架构师划分的领域模型和聚合往往与真实的情况差别较大~ 即使划分的较好~新的业务和变化的业务也另设计师非常头疼~ 另外 设计师很难将庞大复杂的业务抽象成领域模型 往往需要

基于WPF系统框架设计(6) 整合MVVM框架(Prism)

我们基础的框架已经搭建起来了,现在整合MVVM框架Prism,在ViewModel做一些逻辑处理,真正把界面设 计分离出来. 这样方便我们系统开发分工合作,同时提高系统可维护性和灵活性. 具体的 Prism安装和Microsoft.Practices.Prism.dll获取,在这个网址:http://compositewpf.codeplex.com/ 跟Winform一样原始的模式: (1)现在看一下之前的设计的View: MainWindow.XAML源码: (2)MainWindow.xa

c# 框架 开发-C# 的主流框架是???

问题描述 C# 的主流框架是??? Java有Spring C++有MFC C#的主流框架是??? 解决方案 WPF.很不错的. ....

一个快速集成框架:MVP+Dagger+主流框架,有它足矣

前言 今年的Android技术圈中MVP,Dagger2,Rxjava,Retrofit这些词汇非常火,随便打开一个技术论坛都充斥着大量的关于这些技术的文章,Github也充斥着各种以基于MVP+Retrofit+RxJava+Dagger2+MaterialDesign开发的xxxx为标题的开源项目或Demo. 但是大家这么热心的开源此类项目,一直重复的做着同样的事教授大家使用的方式和技巧有没有想过依赖一个第三方库,就可以快速的搭建此类框架? 特性 自动生成MVP,Dagger2相关类 版本更

SilverLight企业应用框架设计【二】框架画面

框架画面分为上中下三层 由下面一个Grid控件完成布局 <Grid x:Name="LayoutRoot"> <Grid.RowDefinitions> <RowDefinition Height="60"></RowDefinition> <RowDefinition Height="*"></RowDefinition> <RowDefinition Height=

《JavaScript框架设计》——导读

前言 首先说明一下,本书虽是讲解框架设计,但写个框架不是很深奥的事情,重点是建立更为完整的前端知识树.只有自己尝试写个框架,才有机会接触像原型.作用域.事件代理.缓存系统.定时器等深层知识,也才有机会了解applyElement.swapNode.importNode.removeNode.replaceNode.insertAdjacentHTML.createContextualFragment.runtimeStyle等偏门API,也才会知晓像getElementById.getEleme

ios 框架设计是什么 怎么做

问题描述 ios 框架设计是什么 怎么做 第一天上班 老大就叫我做框架设计 但是我连框架设计-都不知道 解决方案 http://www.open-open.com/lib/view/open1343210425380.html 解决方案二: ios 一般的应用开发所说的框架都是指app框架.就是你的app的设计模块.底层框架一般人写不了 解决方案三: 你就看你们的 项目需要哪些功能,然后将第三方加进去,该封装的 封装,mvc模式往上怼,改配置的配置

WinForm企业应用框架设计【一】界限划分与动态创建WCF服务(no svc!no serviceActivations!)

WinForm企业应用框架设计[一]界限划分与动态创建WCF服务(no svc!no serviceActivations!) WinForm企业应用框架设计[二]团队内部的约定和客户端按约定识别WCF服务 WinForm企业应用框架设计[三]框架窗体设计:动态创建菜单: WinForm企业应用框架设计[四]动态创建业务窗体 WinForm企业应用框架设计[五]系统登录以及身份验证+源码 先来张图片!我们这个系列就是要做一个这样的框架!    我曾写过几个"系列"的东西,如 PL/SQ

WinForm企业应用框架设计【五】系统登录以及身份验证+源码

索引 WinForm企业应用框架设计[一]界限划分与动态创建WCF服务(no svc!no serviceActivations!) WinForm企业应用框架设计[二]团队内部的约定和客户端按约定识别WCF服务 WinForm企业应用框架设计[三]框架窗体设计:动态创建菜单: WinForm企业应用框架设计[四]动态创建业务窗体 WinForm企业应用框架设计[五]系统登录以及身份验证+源码 闲话休提~ 一:登录的画面与客户端逻辑 为了在打开程序的时候先弹出登录窗体 我们修改了主窗体的构造函数