原生domReady封装

核心思路:

标准浏览器(含IE9+)比较简单,直接监听DOMContentLoaded事件;

低版本的IE(IE678)两套机制:

1)尝试轮询document.documentElement.doScroll("left")是否报错,若报错则dom树结构未ready,否则dom ready;

2)监听document的onreadystatechange事件,判断document.readyState是否为"complete"。

参考:http://javascript.nwbox.com/IEContentLoaded/

 

直接上源码了:

    var domReady = (function () {
        var doc = document,
            branch = document.addEventListener ? 'w3c' : 'ie678';

        var _domReady = {
            // When _domReady.done is true,all 'fn' will be invoked immediately.
            done: false,
            // The stack which all functions will be pushed into
            fn: [],
            // push callback functions
            push: function (fn) {
                if (!_domReady.done) {
                    // only bind once
                    if (_domReady.fn.length === 0) {
                        _domReady.bind();
                    }
                    _domReady.fn.push(fn);
                } else {
                    fn();
                }
            },
            // The Real DOMContentLoaded Callback Function
            ready: function () {
                // Flag DOMContentLoaded Event was Done over
                _domReady.done = true;

                var fn = _domReady.fn;
                for (var i = 0, l = fn.length; i < l; i++) {
                    fn[i]();
                }

                _domReady.unbind();
                _domReady.fn = null;
            },
            bind: {
                w3c: function () {
                    doc.addEventListener('DOMContentLoaded', _domReady.ready, false);
                },
                //IE的监听
                ie678: function () {
                    var done = false,
                        // only fire once
                        init = function () {
                            if (!done) {
                                done = true;
                                _domReady.ready();
                            }
                        };
                    // polling for no errors
                    (function () {
                        try {
                            // throws errors until after ondocumentready
                            doc.documentElement.doScroll('left');
                        } catch (e) {
                            setTimeout(arguments.callee, 20);
                            return;
                        }
                        // no errors, fire
                        init();
                    })();
                    // trying to always fire before onload
                    doc.onreadystatechange = function () {
                        if (doc.readyState == 'complete') {
                            doc.onreadystatechange = null;
                            init();
                        }
                    };
                }
            }[branch],
            unbind: {
                w3c: function () {
                    doc.removeEventListener('DOMContentLoaded', _domReady.ready, false);
                },
                ie678: function () { /* Nothing to do */
                }
            }[branch]
        };

        return _domReady.push;
    })();

 

使用方法:

可以尝试跟window.onload做个比较

    window.onload = function(){
        alert("onload");
    };

    domReady(function(){
        alert("domReady 1");
    });

    domReady(function(){
        alert("domReady 2");
    });

 

 

 

posted @ 2014-05-17 23:58  司马缸  阅读(351)  评论(0编辑  收藏  举报