栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > Web开发 > JavaScript

详解Jquery实现ready和bind事件

JavaScript 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

详解Jquery实现ready和bind事件

讲这一节之前,先回顾之前一段代码:

  (function (win) {
      var _$ = function (selector, context) {
 return new _$.prototype.Init(selector, context);
      }
      _$.prototype = {
 Init: function (selector, context) {
   this.elements = [];
   var context = context || document;
   if (context.querySelectorAll) {
     var arr = context.querySelectorAll(selector);
     for (var i = 0; i < arr.length; i++) {
this.elements.push(arr[i]);
     }
   }
   ////这一块是选择器的实现,没有写完,可以自己实现
 },
 each: function (callback) {
   if (this.elements.length > 0) {
     for (var i = 0; i < this.elements.length; i++) {
callback.call(this, i, this.elements[i]);
     }
   }
 }
      }
      _$.prototype.Init.prototype = _$.prototype;
      window.$ = _$;
    })(window || global);

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

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

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

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

 Init: function (selector, context) {
   this.elements = [];
   if (typeof selector === "function") {
     this.elements.push(document);
     this.ready(selector);
   }
   else {
     var context = context || document;
     var isdocument = function (ele) {
var tostring = Object.prototype.toString;
return tostring.call(ele) == "[object HTMLdocument]" || "[object document]";
     }
     if (isdocument(selector)) {
this.elements.push(selector);
     }
     else if (context.querySelectorAll) {
var arr = context.querySelectorAll(selector);
for (var i = 0; i < arr.length; i++) {
  this.elements.push(arr[i]);
}
     }
   }
 }

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

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

  ready: function (callback) {
   var isdocument = function (ele) {
     var tostring = Object.prototype.toString;
     return tostring.call(ele) == "[object HTMLdocument]" | "[object document]";
   }
   if (isdocument(this.elements[0])) {
     if (document.addEventListener) {
document.addEventListener('DOMContentLoaded', function () {
  document.removeEventListener('DOMContentLoaded', arguments.callee, false);
  callback();
}, false);
     }
     else if (document.attachEvent) {
document.attachEvent('onreadystatechange', function () {
  if (document.readyState == "complete") {
    document.detachEvent('onreadystatechange', arguments.callee);
    callback();
  }
});
     }
     else if (document.lastChild == document.body) {
callback();
     }
   }
 }

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

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

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

 bind: function (type, callback) {
   if (document.addEventListener) {
     this.each(function (i, item) {
item.addEventListener(type, callback, false);
     });
   }
   else if (document.attachEvent) {
     this.each(function (i, item) {
item.attachEvent('on' + type, callback);
     });
   }
   else {
     this.each(function (i, item) {
tem['on' + type] = callback;
     });
   }

 }

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

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

完整代码,来一份:

    (function (win) {
      var _$ = function (selector, context) {
 return new _$.prototype.Init(selector, context);
      }
      _$.prototype = {
 Init: function (selector, context) {
   this.elements = [];
   if (typeof selector === "function") {
     this.elements.push(document);
     this.ready(selector);
   }
   else {
     var context = context || document;
     var isdocument = function (ele) {
var tostring = Object.prototype.toString;
return tostring.call(ele) == "[object HTMLdocument]" | "[object document]";
     }
     if (isdocument(selector)) {
this.elements.push(selector);
     }
     else if (context.querySelectorAll) {
var arr = context.querySelectorAll(selector);
for (var i = 0; i < arr.length; i++) {
  this.elements.push(arr[i]);
}
     }
   }
 },
 each: function (callback) {
   var length = this.elements.length;
   if (length > 0) {
     for (var i = 0; i < length; i++) {
callback.call(this, i, this.elements[i]);
     }
   }
 },
 ready: function (callback) {
   var isdocument = function (ele) {
     var tostring = Object.prototype.toString;
     return tostring.call(ele) == "[object HTMLdocument]" | "[object document]";
   }
   if (isdocument(this.elements[0])) {
     if (document.addEventListener) {
document.addEventListener('DOMContentLoaded', function () {
  document.removeEventListener('DOMContentLoaded', arguments.callee, false);
  callback();
}, false);
     }
     else if (document.attachEvent) {
document.attachEvent('onreadystatechange', function () {
  if (document.readyState == "complete") {
    document.detachEvent('onreadystatechange', arguments.callee);
    callback();
  }
});
     }
     else if (document.lastChild == document.body) {
callback();
     }
   }
 },
 bind: function (type, callback) {
   if (document.addEventListener) {
     this.each(function (i, item) {
item.addEventListener(type, callback, false);
     });
   }
   else if (document.attachEvent) {
     this.each(function (i, item) {
item.attachEvent('on' + type, callback);
     });
   }
   else {
     this.each(function (i, item) {
tem['on' + type] = callback;
     });
   }

 }
      }
      _$.prototype.Init.prototype = _$.prototype;
      window.$ = _$;
    })(window);


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

以上就是本文的全部内容,希望能够帮助大家。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/97606.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号