forked from requirejs/requirejs
-
Notifications
You must be signed in to change notification settings - Fork 0
/
domReady.js
170 lines (150 loc) · 5.37 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
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
/**
* @license RequireJS domReady 1.0.0 Copyright (c) 2010-2011, The Dojo Foundation All Rights Reserved.
* Available via the MIT or new BSD license.
* see: http://github.com/jrburke/requirejs for details
*/
/*jslint strict: false, plusplus: false */
/*global require: false, define: false, requirejs: false,
window: false, clearInterval: false, document: false,
self: false, setInterval: false */
define(function () {
var isBrowser = typeof window !== "undefined" && window.document,
isPageLoaded = !isBrowser,
doc = isBrowser ? document : null,
readyCalls = [],
readyLoaderCalls = [],
//Bind to a specific implementation, but if not there, try a
//a generic one under the "require" name.
req = requirejs || require || {},
oldResourcesReady = req.resourcesReady,
scrollIntervalId;
function runCallbacks(callbacks) {
for (var i = 0, callback; (callback = callbacks[i]); i++) {
callback(doc);
}
}
function callReady() {
var callbacks = readyCalls,
loaderCallbacks = readyLoaderCalls;
if (isPageLoaded) {
//Call the DOM ready callbacks
if (callbacks.length) {
readyCalls = [];
runCallbacks(callbacks);
}
//Now handle DOM ready + loader ready callbacks.
if (req.resourcesDone && loaderCallbacks.length) {
readyLoaderCalls = [];
runCallbacks(loaderCallbacks);
}
}
}
/**
* Add a method to require to get callbacks if there are loader resources still
* being loaded. If so, then hold off calling "withResources" callbacks.
*
* @param {Boolean} isReady: pass true if all resources have been loaded.
*/
if ('resourcesReady' in req) {
req.resourcesReady = function (isReady) {
//Call the old function if it is around.
if (oldResourcesReady) {
oldResourcesReady(isReady);
}
if (isReady) {
callReady();
}
};
}
/**
* Sets the page as loaded.
*/
function pageLoaded() {
if (!isPageLoaded) {
isPageLoaded = true;
if (scrollIntervalId) {
clearInterval(scrollIntervalId);
}
callReady();
}
}
if (isBrowser) {
if (document.addEventListener) {
//Standards. Hooray! Assumption here that if standards based,
//it knows about DOMContentLoaded.
document.addEventListener("DOMContentLoaded", pageLoaded, false);
window.addEventListener("load", pageLoaded, false);
} else if (window.attachEvent) {
window.attachEvent("onload", pageLoaded);
//DOMContentLoaded approximation, as found by Diego Perini:
//http://javascript.nwbox.com/IEContentLoaded/
if (self === self.top) {
scrollIntervalId = setInterval(function () {
try {
//From this ticket:
//http://bugs.dojotoolkit.org/ticket/11106,
//In IE HTML Application (HTA), such as in a selenium test,
//javascript in the iframe can't see anything outside
//of it, so self===self.top is true, but the iframe is
//not the top window and doScroll will be available
//before document.body is set. Test document.body
//before trying the doScroll trick.
if (document.body) {
document.documentElement.doScroll("left");
pageLoaded();
}
} catch (e) {}
}, 30);
}
}
//Check if document already complete, and if so, just trigger page load
//listeners.
if (document.readyState === "complete") {
pageLoaded();
}
}
/** START OF PUBLIC API **/
/**
* Registers a callback for DOM ready. If DOM is already ready, the
* callback is called immediately.
* @param {Function} callback
*/
function domReady(callback) {
if (isPageLoaded) {
callback(doc);
} else {
readyCalls.push(callback);
}
return domReady;
}
/**
* Callback that waits for DOM ready as well as any outstanding
* loader resources. Useful when there are implicit dependencies.
* This method should be avoided, and always use explicit
* dependency resolution, with just regular DOM ready callbacks.
* The callback passed to this method will be called immediately
* if the DOM and loader are already ready.
* @param {Function} callback
*/
domReady.withResources = function (callback) {
if (isPageLoaded && req.resourcesDone) {
callback(doc);
} else {
readyLoaderCalls.push(callback);
}
return domReady;
};
domReady.version = '1.0.0';
/**
* Loader Plugin API method
*/
domReady.load = function (name, req, onLoad, config) {
if (config.isBuild) {
onLoad(null);
} else {
domReady(onLoad);
}
};
/** END OF PUBLIC API **/
return domReady;
});