Jquery揭秘系列:实现 ready和bind事件

 

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

    (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对象里面加方法。

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

 
 
分类: JS/JQUERY

实现 ready和bind事件的更多相关文章

  1. Jquery揭秘系列:实现 ready和bind事件

    讲这一节之前,先回顾之前的一篇<小谈Jquery>里面的代码: (function (win) { var _$ = function (selector, context) { retu ...

  2. jQuery中ready与load事件

    jQuery中ready与load事件(来自慕课网) jQuery有3种针对文档加载的方法 $(document).ready(function() { // ...代码... }) //docume ...

  3. jQuery学习一:jQuery中的ready和load事件

    //ready事件 $(document).ready(function(){ 代码........ }); //ready事件简写: $(function(){ 代码........ }); //l ...

  4. js的onclick和jquery的bind事件执行先后顺序

    近期在项目中为每一个ajax触发按钮写正在加载的效果,用的是bootstarp 代码如下 $(function(){ $('.btn').bind('click',function(e){ var $ ...

  5. [jQuery]on和bind事件绑定的区别

    on和bind事件绑定的区别 一个demo展示 <!DOCTYPE html> <html lang="zh"> <head> <titl ...

  6. JQuery 的Bind()事件

    刚开始我们先看一下它的定义: .bind( eventType [, eventData], handler(eventObject)) .Bind()方法的主要功能是在向它绑定的对象上面提供一些事件 ...

  7. GUI tkinter (bind)事件篇

    """事件:1.我们的很多操作,比如我们点击了一下鼠标,这就是一 个事件,而操作系统会根据我们的相应的事件产生相应的消息, 操作系统把消息传递给我们的应用程序,然后我们的 ...

  8. TKinter当Label绑定bind事件时传参方法

    记录下tkinter的 当在label绑定bind事件时,遇到需要传参时的解决方法(因为有event存在 所以不能直接传参) https://www.cnblogs.com/liyuanhong/ar ...

  9. jquery事件三 -- load(), ready(), resize()以及bind()事件

    例子1 ready() DOM加载完毕 load() 元素加载完毕 resize() 浏览器窗口的大小发生变化 <!DOCTYPE html> <html lang="en ...

随机推荐

  1. 【软件project】生存期模型(含图)

    为了反映软件生存周期内各个工作应怎样组织,各阶段怎样衔接,须要软件开发模型给出直观图示表达.软件开发模型是软件思想的详细化,是实施在过程模块中的软件开发方法和工具. 以下来介绍开发模型的特点以及他们的 ...

  2. ASP.NET——两个下拉框来实现动态联动

    介绍: 在网页中.我们常常会遇到下图中的情况.首先在下拉框中选择所在的省.选择之后,第二个下拉框会自己主动载入出该省中的市.这样设计极大的方便了用户的查找.那这是怎样实现的呢? 1.建立数据库 &qu ...

  3. C/C++各种类型int、long、double、char表示范围(最大和最小)

    #include<iostream> #include<string> #include <limits> using namespace std; int mai ...

  4. IMSDroid遇到注册问题(蘼1S 计3等一下 Android4.4)

    最近的研究视频通话,开源项目IMSDroid编译测试,这实在是不幸的,饭1 Android4.1和大米3 Android4.4该系统不是对生命和死亡登记.... .后来通过大神日志分析和建议.发现改变 ...

  5. 【Android UI设计和开发】动画(Animation)详细说明(一)

    Android开发之动画效果浅析 请尊重他人的劳动成果.转载请注明出处:Android开发之动画效果浅析 程序执行效果图: Android动画主要包括补间动画(Tween)View Animation ...

  6. Swift语言指南(六)--可选值

    原文:Swift语言指南(六)--可选值 在值可能不存在的情况下使用可选值(optional), 可选值是: · 存在一个值,这个值等于 x 或 · 不存在任何值 注: 在 C 和 Objective ...

  7. 步步详解近期大火的density_peak超赞聚类

    近期忙着在公司捣腾基于SOA的应急框架,还是前两周才在微博上看见了density_peak,被圈内好些人转载. 由于这个算法的名字起的实在惹眼,都没好意思怎么把这个算法名字翻译成中文,当然更惹眼的是, ...

  8. Codeforces 437D The Child and Zoo(贪心+并查集)

    题目链接:Codeforces 437D The Child and Zoo 题目大意:小孩子去參观动物园,动物园分非常多个区,每一个区有若干种动物,拥有的动物种数作为该区的权值.然后有m条路,每条路 ...

  9. STL在迭代的过程,删除指定的元素

    直接在Code.在 Picture #include <iostream> #include <list> using namespace std; // STL在迭代的过程中 ...

  10. Android开发----------- 手电筒改进版本号

    在之前的基础上 在 res 目录以下: 加入一个 drawable/local_me.xml localme_cml <selector xmlns:android="http://s ...