Web 技术研究所

我一直坚信着,Web 将会成为未来应用程序的主流

jQuery的ready“事件”?

  在jQuery中使用ready有很多种写法,那些简短的写法在使用上提供了很多便利。但是对jQuery而言,ready真的是一个“事件”吗? 虽然逻辑上ready是一个文档级的事件,绑定方法也和普通的事件类似。但是jQuery并没有把它当做普通的事件来处理。
  下面这么多种方式都可以绑定一个ready $(function(){
  console.log(1);
});
$(document).ready(function(){
  console.log(2);
});
$(document).on("ready",function(){
  console.log(3);
});
$(window).on("ready",function(){
  console.log(4);
});
  我当然不会无聊到来讨论茴香豆般的问题的,这些写法在功能上是会有差异的。我们用的最多的是第一种写法吧?因为它简单,第一种写法确实只是一个缩写,它在内部调用了第二种写法(jquery-1.9.1.js 213行),所以前两种方法是完全一样的。在jQuery内部有一个readyList用来存放这前两种方法添加的回调函数,它是一个Deferred对象。Deferred对象绑定的函数是一次调用的,也就是说成功调用一次resolve之后它的状态就被标识为了resolved,之后的resolve就不再生效。因此,这些ready“事件”在触发一次后就无法再使用了。
  前面的两种写法甚至没有绑定在DOM上,只是jQuery内部的一个Deferred对象来负责的。那第三种方式绑定的事件为什么会执行呢?其实jQuery也有点小晦涩,它对绑定在document上的ready事件做了单独的解析,并且在执行完之后移除了它(jquery-1.9.1.js 437行)。所以在文档加载完成之前绑定在document上的ready事件和使用前两种方式绑定的结果是一样的。但是在文档加载完成之后绑定就不同了!前两种方式在绑定时多了一个判断,如果文档已经加载完成则直接把传入的函数丢进消息队列中等待执行(jquery-1.9.1.js 893行)。对于document上的ready事件只是作为普通的事件而已,jQuery对它做了额外的触发,所以文档加载完成后再绑定到document上的ready是无法被调用到的。
onload=function(){
  $(function(){
    console.log(1); //正常执行
  });
  $(document).on("ready",function(){
    console.log(3); //不会执行
  });
};
  那么最后一种情况呢?ready触发时jQuery只处理了document,那么直接在window上绑定的ready被谁调用到了?事实上,直接在document上绑定是ready被jQuery视为了自定义事件。在jQuery中自定义事件是可以冒泡的,所以对document调用trigger时会冒泡到window上从而触发了window上的ready。而且jQuery在trigger完document的ready事件之后调用了off来移除,而没对window执行移除,因此绑定在window上的ready事件可以在任何时候调用trigger触发。这是前面几种方式做不到的。在一开始的测试代码中添加个点击事件来触发就可以测试出来。 $(document).click(function(){
  $(this).trigger("ready");
});
  我就不截图了,点击文档时只有“4”被多次输出了。还可以这样测试,在document的ready事件中停止冒泡。 $(document).on("ready",function(e){
  console.log(3); //正常执行
  e.stopPropagation();
});
$(window).on("ready",function(){
  console.log(4); //不会执行
});
  这些不同写法的不同特性可以在不同的需求中使用,jQuery的ready也不是个简单的东西。
网名:
34.203.213.*
电子邮箱:
仅用于接收通知
提交 悄悄的告诉你,Ctrl+Enter 可以提交哦
神奇海螺
[查看全部主题]
各类Web技术问题讨论区
发起新主题
本模块采用即时聊天邮件通知的模式
让钛合金F5成为历史吧!
次碳酸钴的技术博客,文章原创,转载请保留原文链接 ^_^