domReady.js 3.1 KB

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