jquery event domready

  1. Domready是每个lib都要实现的函数,因为dom还没有完全ready,那么对于对于dom元素的操作可能出错,因为dom树中可能还没有Load这个元素。为了保障不出现这样的错误,就出现地domready。对于每种浏览器Domready都有着自己不同的判断。
  2. Jquery的domready的实现和其它的lib的实现没有什么区别。
  3. //dom ready时执行 fn
  4. ready : function(fn) {
  5. bindReady();//注册监听
  6. if (jQuery.isReady)//ready就运行
  7. fn.call(document, jQuery);
  8. else
  9. // 增加这个函数到queue中。可见支持无数的ready的调用。
  10. jQuery.readyList.push(function() {
  11. return fn.call(this, jQuery);
  12. });
  13. returnthis;
  14. }
  15. 我们通过$(fn)的方法就是在调用这个方法。它首先通过bindReady()来注册监听dom是否已经loaded。如果已经loaded就运行fn。如果没有就把fn存放在readyList中。对于多个$(fn),把它们各自的fn参数保存在公共的jQuery. readyList的公共集合中。待到dom loaed之后统一运行。对于dom 已经loaded,就可以分别去运行fn。
  16. var readyBound = false;
  17. function bindReady() {
  18. if (readyBound)
  19. return;
  20. readyBound = true;
  21. // Mozilla, Opera, webkit nightlies 支持DOMContentLoaded事件
  22. if (document.addEventListener && !jQuery.browser.opera)
  23. //当DOMContentLoaded事件触发时就运行jQuery.ready
  24. document.addEventListener("DOMContentLoaded", jQuery.ready, false);
  25. //IE或不是frame的window
  26. if (jQuery.browser.msie && window == top)
  27. (function() {
  28. if (jQuery.isReady)
  29. return;
  30. try {
  31. // 在ondocumentready之前,一直都会抛出异常
  32. // http://javascript.nwbox.com/IEContentLoaded/
  33. document.documentElement.doScroll("left");
  34. } catch (error) {
  35. //一直运行bindReady()(=arguments.callee)
  36. setTimeout(arguments.callee, 0);
  37. return;
  38. }
  39. jQuery.ready();//documentready就运行jQuery.ready
  40. })();
  41. if (jQuery.browser.opera)
  42. document.addEventListener("DOMContentLoaded", function() {
  43. if (jQuery.isReady)
  44. return;
  45. //只有styleSheets完全enable时,才是完全的load,其实还有pic
  46. for (var i = 0;i < document.styleSheets.length; i++)
  47. if (document.styleSheets[i].disabled) {//通过styleSheets来判断
  48. setTimeout(arguments.callee, 0);
  49. return;
  50. }
  51. jQuery.ready();
  52. }, false);
  53. if (jQuery.browser.safari) {
  54. var numStyles;
  55. (function() {
  56. if (jQuery.isReady)
  57. return;
  58. //首先得得到readyState=loaded或=complete
  59. if (document.readyState != "loaded"
  60. && document.readyState != "complete") {
  61. setTimeout(arguments.callee, 0);
  62. return;
  63. }
  64. //取得style的length,比较它们之间的长度,看看是不是完成loaded
  65. if (numStyles === undefined)
  66. numStyles = jQuery("style,
  67. link[rel=stylesheet]").length;
  68. if (document.styleSheets.length != numStyles) {
  69. setTimeout(arguments.callee, 0);
  70. return;
  71. }
  72. jQuery.ready();
  73. })();
  74. }
  75. //最后只能依赖于window.load.
  76. jQuery.event.add(window, "load", jQuery.ready);
  77. }
  78. 这段代码看起来很多,其实就是采用setTimeout(arguments.callee, 0);反复来运行bindReady。如果其得到dom ready的条件满足的话,就执行jQuery.ready()来执行通过$(fn)注册的fn函数。对于每种浏览器,这个满足的条件是不一样。上面的代码就是针对于几种常用的浏览器分别做了各自的处理。
  79. isReady : false,
  80. readyList : [],
  81. // Handle when the DOM is ready
  82. ready : function() {
  83. if (!jQuery.isReady) {
  84. jQuery.isReady = true;
  85. if (jQuery.readyList) {
  86. jQuery.each(jQuery.readyList, function() {
  87. this.call(document);
  88. });
  89. jQuery.readyList = null;
  90. }
  91. jQuery(document).triggerHandler("ready");
  92. }
  93. }
  94. });
  95. 当运行到jQuery.ready()的时候就说明dom已经完全的Loaded,那么现在就应该执行保存在jQuery.readyList中的fn。jQuery.ready()就是完成这个工作。