讲这一节之前,先回顾之前的一篇《小谈Jquery》里面的代码:

  1. (function (win) {
  2. var _$ = function (selector, context) {
  3. return new _$.prototype.Init(selector, context);
  4. }
  5. _$.prototype = {
  6. Init: function (selector, context) {
  7. this.elements = [];
  8. var context = context || document;
  9. if (context.querySelectorAll) {
  10. var arr = context.querySelectorAll(selector);
  11. for (var i = 0; i < arr.length; i++) {
  12. this.elements.push(arr[i]);
  13. }
  14. }
  15. ////这一块是选择器的实现,没有写完,可以自己实现
  16. },
  17. each: function (callback) {
  18. if (this.elements.length > 0) {
  19. for (var i = 0; i < this.elements.length; i++) {
  20. callback.call(this, i, this.elements[i]);
  21. }
  22. }
  23. }
  24. }
  25. _$.prototype.Init.prototype = _$.prototype;
  26. window.$ = _$;
  27. })(window || global);

上面我们实现了节点的查找,今天要讲的是对节点的事件绑定。

熟悉Jquery 源码的TX应该知道:我们上面的代码少了ready事件,只是针对节点进行查询,并没有将document对象考虑进去。我之前单独讲过window.onload和 document. ready的区别,还对document.ready事件进行了扩展。

现在我们把扩展方法加到这里面:

我们的Init方法要改正一下:

  1. Init: function (selector, context) {
  2. this.elements = [];
  3. if (typeof selector === "function") {
  4. this.elements.push(document);
  5. this.ready(selector);
  6. }
  7. else {
  8. var context = context || document;
  9. var isDocument = function (ele) {
  10. var tostring = Object.prototype.toString;
  11. return tostring.call(ele) == "[object HTMLDocument]" || "[object Document]";
  12. }
  13. if (isDocument(selector)) {
  14. this.elements.push(selector);
  15. }
  16. else if (context.querySelectorAll) {
  17. var arr = context.querySelectorAll(selector);
  18. for (var i = 0; i < arr.length; i++) {
  19. this.elements.push(arr[i]);
  20. }
  21. }
  22. }
  23. }

这段代码的大致意思是:如果传入的参数selector是function类型,就执行ready事件。如果是document就将document对象插入到this.elements数组里面(这个传入之后,会在ready事件里面进行判断)。如果是字符窜,就查询出节点,循环插入到this.elements数组里面,没什么难度。主要考虑到$(document).ready和$(function(){})这两种ready事件的写法。

我们接下来把ready函数加进来:

  1. ready: function (callback) {
  2. var isDocument = function (ele) {
  3. var tostring = Object.prototype.toString;
  4. return tostring.call(ele) == "[object HTMLDocument]" | "[object Document]";
  5. }
  6. if (isDocument(this.elements[0])) {
  7. if (document.addEventListener) {
  8. document.addEventListener('DOMContentLoaded', function () {
  9. document.removeEventListener('DOMContentLoaded', arguments.callee, false);
  10. callback();
  11. }, false);
  12. }
  13. else if (document.attachEvent) {
  14. document.attachEvent('onreadystatechange', function () {
  15. if (document.readyState == "complete") {
  16. document.detachEvent('onreadystatechange', arguments.callee);
  17. callback();
  18. }
  19. });
  20. }
  21. else if (document.lastChild == document.body) {
  22. callback();
  23. }
  24. }
  25. }

这段代码我之前其实讲过了(onload和ready的区别),不知道的可以看看。

现在ready事件,我们实现了。然后就可以针对节点进行事件注册了。

我们来实现bind函数,代码如下:

  1. bind: function (type, callback) {
  2. if (document.addEventListener) {
  3. this.each(function (i, item) {
  4. item.addEventListener(type, callback, false);
  5. });
  6. }
  7. else if (document.attachEvent) {
  8. this.each(function (i, item) {
  9. item.attachEvent('on' + type, callback);
  10. });
  11. }
  12. else {
  13. this.each(function (i, item) {
  14. tem['on' + type] = callback;
  15. });
  16. }
  17.  
  18. }

这里面都是些兼容性代码,实现节点的事件注册。之前的each,大家可能不知道是要干嘛的。现在在这里面就用到了。

主要作用是针对节点循环做一些操作。

完整代码,来一份:

  1. (function (win) {
  2. var _$ = function (selector, context) {
  3. return new _$.prototype.Init(selector, context);
  4. }
  5. _$.prototype = {
  6. Init: function (selector, context) {
  7. this.elements = [];
  8. if (typeof selector === "function") {
  9. this.elements.push(document);
  10. this.ready(selector);
  11. }
  12. else {
  13. var context = context || document;
  14. var isDocument = function (ele) {
  15. var tostring = Object.prototype.toString;
  16. return tostring.call(ele) == "[object HTMLDocument]" | "[object Document]";
  17. }
  18. if (isDocument(selector)) {
  19. this.elements.push(selector);
  20. }
  21. else if (context.querySelectorAll) {
  22. var arr = context.querySelectorAll(selector);
  23. for (var i = 0; i < arr.length; i++) {
  24. this.elements.push(arr[i]);
  25. }
  26. }
  27. }
  28. },
  29. each: function (callback) {
  30. var length = this.elements.length;
  31. if (length > 0) {
  32. for (var i = 0; i < length; i++) {
  33. callback.call(this, i, this.elements[i]);
  34. }
  35. }
  36. },
  37. ready: function (callback) {
  38. var isDocument = function (ele) {
  39. var tostring = Object.prototype.toString;
  40. return tostring.call(ele) == "[object HTMLDocument]" | "[object Document]";
  41. }
  42. if (isDocument(this.elements[0])) {
  43. if (document.addEventListener) {
  44. document.addEventListener('DOMContentLoaded', function () {
  45. document.removeEventListener('DOMContentLoaded', arguments.callee, false);
  46. callback();
  47. }, false);
  48. }
  49. else if (document.attachEvent) {
  50. document.attachEvent('onreadystatechange', function () {
  51. if (document.readyState == "complete") {
  52. document.detachEvent('onreadystatechange', arguments.callee);
  53. callback();
  54. }
  55. });
  56. }
  57. else if (document.lastChild == document.body) {
  58. callback();
  59. }
  60. }
  61. },
  62. bind: function (type, callback) {
  63. if (document.addEventListener) {
  64. this.each(function (i, item) {
  65. item.addEventListener(type, callback, false);
  66. });
  67. }
  68. else if (document.attachEvent) {
  69. this.each(function (i, item) {
  70. item.attachEvent('on' + type, callback);
  71. });
  72. }
  73. else {
  74. this.each(function (i, item) {
  75. tem['on' + type] = callback;
  76. });
  77. }
  78.  
  79. }
  80. }
  81. _$.prototype.Init.prototype = _$.prototype;
  82. window.$ = _$;
  83. })(window);

这几个函数基本上可以实现对节点的事件注册了。其余的一些特效啥的,还需要扩展。如果感兴趣的话可以自己在  _$.prototype对象里面加方法。

如果有疑问或者意见的TX直接留言吧。反正大家是互相学习,互相交流。

Jquery揭秘系列:实现 ready和bind事件的更多相关文章

  1. 实现 ready和bind事件

    Jquery揭秘系列:实现 ready和bind事件   讲这一节之前,先回顾之前的一篇<小谈Jquery>里面的代码: (function (win) { var _$ = functi ...

  2. Jquery揭秘系列:Validation实现

    之前讲了一部分揭秘系列的东西,由于年初的时候在改项目,也没有写下去.现在开始闲下来了,会继续写没写完的东西,各种原生js实现Jquery的功能. 转入正题,说一下今天要讲的东西. 相信很多tx在项目里 ...

  3. Jquery揭秘系列:谈谈bind,one,live,delegate事件及实现

    在Jquery里面,我们用的最多的就是事件绑定了,事件绑定有多个函数.例如:bind,one,live,delegate等等. 我们先看看他们的定义,直接进入主题: bind( )方法用于将一个处理程 ...

  4. Jquery揭秘系列:谈谈bind,one,live,delegate,on事件及实现

    在Jquery里面,我们用的最多的就是事件绑定了,事件绑定有多个函数.例如:bind,one,live,delegate,on等等. on() jQuery事件绑定.on()简要概述及应用 看源码发现 ...

  5. [jQuery学习系列四 ]4-Jquery学习四-事件操作

    前言:今天看知乎偶然看到中国有哪些类似于TED的节目, 回答中的一些推荐我给记录下来了, 顺便也在这里贴一下: 一席 云集 听道 推酷 青年中国说 SELF格致论道 参考:http://www.365 ...

  6. Jquery揭秘系列:实现$.fn.extend 和$.extend函数

    前面我们扩展了bind方法和ready函数,这次我要讲一下$.fn.extend 和$.extend函数. 其他的不多说,直接切入主题吧! 先来看看这两个函数的区别: $.fn.extend是为查询的 ...

  7. 原 jQuery中document的ready和load事件的区别?

    概述: 大家在工作中用jQuery的时候一定会在使用之前这样:   1 2 3 4 5 6 7 8 //document ready $(document).ready(function(){     ...

  8. jQuery原理系列-Dom Ready

    ready事件是jquery的一个很重要的功能,在很久很久以前,我们是使用window.onload监听页面加载成功的,onload事件的好处是你不用考虑浏览器兼容性,也不需要依赖任何框架就可以写,但 ...

  9. Jquery揭秘系列:ajax原生js实现

    讲到ajax这个东西,我们要知道两个对象XMLHTTPRequest和ActiveXObject ,提供了对 HTTP 协议的完全的访问,包括做出 POST 和 HEAD 请求以及普通的 GET 请求 ...

随机推荐

  1. 基本排序算法——插入排序java实现

    插入排序过程: 在初始状态下,第一个元素是排序的,在最终状态下,作为一组数据时排序的. 代码如下;eclipse4.3实现 package sort.basic; import java.util.A ...

  2. 获取WIFI密码

    在十年前,我还在上初中,班上只有极少数的富二代用得起手机:几年后诺基亚.摩托罗拉.三星手机开始盛行:近些年,安卓.苹果系统手机占据了基本整个市场,WIFI出变得越来越重要. Wifi万能钥匙数据库存储 ...

  3. iOS之自定义pickerview(行驶里程数)

    #pragma mark -- 里程数按钮的点击事件 - (void)mileageBtnClicked:(UIButton *)sender { UIAlertController *alert = ...

  4. 简单的学习心得:网易云课堂Android开发第三章自定义控件

    这一章分三部分: (1)自定义控件:老师先简单讲解了一些细节,如为什么不用px,而要用dp,只因机型的屏幕分辨率不同,用px会导致差异太大.然后演示了制作自定义控件的步骤,先在xml文件中添加对应的自 ...

  5. iOS---A valid provisioning profile for this executable was not found

    把Target中的Code Signing Identity也设置成iPhone Develop就ok了,这样一切都说的通了,唯一不合理的就是在Project切换Code Signing Identi ...

  6. php面向对象编程 设计模式

    面向对象编程的基本原则: 单一职责:一个类,只需要做好一件事 开放封闭:一个类,应该是可扩展的,而不是可修改的 依赖倒置:一个类,不应该强依赖另一个类.每个类对应另外一个类都是可替换的 配置化:尽可能 ...

  7. MySQL学习笔记之视图

    视图是对磁盘上保存的表数据的抽象,即抽取一个表或多个表的部分行或列的数据,展示给使用者. 首先列举下MySQL中最简单的对视图操作的语法: 1.创建视图: create view 视图名 as sel ...

  8. mysql 单表排序,相同值排序

    两种方式: 第一种是利用笛卡尔积,两对比排序 -- 学校类型数据 SELECT t.examid,'-' AS unitcode,t.schooltype,'-' AS classname,t.bkr ...

  9. 致命错误: zlib.h:没有那个文件或目录

    下面这个错误是因为zlib包没有安装,安装后问题即可解决.但有一点请注意安装命令是:sudo apt-get install zlib1g-dev,而非sudo apt-get install zli ...

  10. I2C基础知识

    常识 两条总线线路:串行数据总线SDA,串行时钟总线SCL 每个连接到总线的器件都有唯一的地址供其他设备寻址 每个连接到总线的器件都可以作为发送器和接收器 是多主机总线,如果两个或更多主机同时初始化, ...