forked from dojo/dojo
-
Notifications
You must be signed in to change notification settings - Fork 0
/
domReady.js
124 lines (107 loc) · 3.11 KB
/
domReady.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
define(['./has'], function(has){
var global = (function () { return this; })(),
doc = document,
readyStates = { 'loaded': 1, 'complete': 1 },
fixReadyState = typeof doc.readyState != "string",
ready = !!readyStates[doc.readyState],
readyQ = [],
recursiveGuard;
function domReady(callback){
// summary:
// Plugin to delay require()/define() callback from firing until the DOM has finished loading.
readyQ.push(callback);
if(ready){ processQ(); }
}
domReady.load = function(id, req, load){
domReady(load);
};
// Export queue so that ready() can check if it's empty or not.
domReady._Q = readyQ;
domReady._onQEmpty = function(){
// summary:
// Private method overridden by dojo/ready, to notify when everything in the
// domReady queue has been processed. Do not use directly.
// Will be removed in 2.0, along with domReady._Q.
};
// For FF <= 3.5
if(fixReadyState){ doc.readyState = "loading"; }
function processQ(){
// Calls all functions in the queue in order, unless processQ() is already running, in which case just return
if(recursiveGuard){ return; }
recursiveGuard = true;
while(readyQ.length){
try{
(readyQ.shift())(doc);
}catch(err){
console.error(err, "in domReady callback", err.stack);
}
}
recursiveGuard = false;
// Notification for dojo/ready. Remove for 2.0.
// Note that this could add more tasks to the ready queue.
domReady._onQEmpty();
}
if(!ready){
var tests = [],
detectReady = function(evt){
evt = evt || global.event;
if(ready || (evt.type == "readystatechange" && !readyStates[doc.readyState])){ return; }
// For FF <= 3.5
if(fixReadyState){ doc.readyState = "complete"; }
ready = 1;
processQ();
},
on = function(node, event){
node.addEventListener(event, detectReady, false);
readyQ.push(function(){ node.removeEventListener(event, detectReady, false); });
};
if(!has("dom-addeventlistener")){
on = function(node, event){
event = "on" + event;
node.attachEvent(event, detectReady);
readyQ.push(function(){ node.detachEvent(event, detectReady); });
};
var div = doc.createElement("div");
try{
if(div.doScroll && global.frameElement === null){
// the doScroll test is only useful if we're in the top-most frame
tests.push(function(){
// Derived with permission from Diego Perini's IEContentLoaded
// http://javascript.nwbox.com/IEContentLoaded/
try{
div.doScroll("left");
return 1;
}catch(e){}
});
}
}catch(e){}
}
on(doc, "DOMContentLoaded");
on(global, "load");
if("onreadystatechange" in doc){
on(doc, "readystatechange");
}else if(!fixReadyState){
// if the ready state property exists and there's
// no readystatechange event, poll for the state
// to change
tests.push(function(){
return readyStates[doc.readyState];
});
}
if(tests.length){
var poller = function(){
if(ready){ return; }
var i = tests.length;
while(i--){
if(tests[i]()){
detectReady("poller");
return;
}
}
setTimeout(poller, 30);
};
poller();
}
}
return domReady;
});