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直接留言吧。反正大家是互相学习,互相交流。
Jquery揭秘系列:实现 ready和bind事件的更多相关文章
- 实现 ready和bind事件
Jquery揭秘系列:实现 ready和bind事件 讲这一节之前,先回顾之前的一篇<小谈Jquery>里面的代码: (function (win) { var _$ = functi ...
- Jquery揭秘系列:Validation实现
之前讲了一部分揭秘系列的东西,由于年初的时候在改项目,也没有写下去.现在开始闲下来了,会继续写没写完的东西,各种原生js实现Jquery的功能. 转入正题,说一下今天要讲的东西. 相信很多tx在项目里 ...
- Jquery揭秘系列:谈谈bind,one,live,delegate事件及实现
在Jquery里面,我们用的最多的就是事件绑定了,事件绑定有多个函数.例如:bind,one,live,delegate等等. 我们先看看他们的定义,直接进入主题: bind( )方法用于将一个处理程 ...
- Jquery揭秘系列:谈谈bind,one,live,delegate,on事件及实现
在Jquery里面,我们用的最多的就是事件绑定了,事件绑定有多个函数.例如:bind,one,live,delegate,on等等. on() jQuery事件绑定.on()简要概述及应用 看源码发现 ...
- [jQuery学习系列四 ]4-Jquery学习四-事件操作
前言:今天看知乎偶然看到中国有哪些类似于TED的节目, 回答中的一些推荐我给记录下来了, 顺便也在这里贴一下: 一席 云集 听道 推酷 青年中国说 SELF格致论道 参考:http://www.365 ...
- Jquery揭秘系列:实现$.fn.extend 和$.extend函数
前面我们扩展了bind方法和ready函数,这次我要讲一下$.fn.extend 和$.extend函数. 其他的不多说,直接切入主题吧! 先来看看这两个函数的区别: $.fn.extend是为查询的 ...
- 原 jQuery中document的ready和load事件的区别?
概述: 大家在工作中用jQuery的时候一定会在使用之前这样: 1 2 3 4 5 6 7 8 //document ready $(document).ready(function(){ ...
- jQuery原理系列-Dom Ready
ready事件是jquery的一个很重要的功能,在很久很久以前,我们是使用window.onload监听页面加载成功的,onload事件的好处是你不用考虑浏览器兼容性,也不需要依赖任何框架就可以写,但 ...
- Jquery揭秘系列:ajax原生js实现
讲到ajax这个东西,我们要知道两个对象XMLHTTPRequest和ActiveXObject ,提供了对 HTTP 协议的完全的访问,包括做出 POST 和 HEAD 请求以及普通的 GET 请求 ...
随机推荐
- iOS 开源项目
在 Github 上 Star 太多了,有时候很难找到自己想要的开源库,所以在此记录下来.便于自己开发使用,也顺便分享给大家. 动画 awesome-ios-animation收集了iOS平台下比较主 ...
- 网络分析之Pgrouting(转载)
网上关于Pgrouting的使用介绍太简单了,这里想详细的总结一下Pgrouting的使用,其实主要参照官方文档:http://workshop.pgrouting.org/ 第一步:配置环境 关于P ...
- C#通过WMI的wind32 的API函数实现msinfo32的本地和远程计算机的系统日志查看功能
先不说如何实现,先来看看效果图: 读取远程的需要提供下远程的计算用户名和密码即可. 如何实现这个代码功能,请看如下代码部分: 实体类: using System; using System.Colle ...
- 用VSCode写python的正确姿势(转载)
最近在学习python,之前一直用notepad++作为编辑器,偶然发现了VScode便被它的颜值吸引.用过之后发现它启动快速,插件丰富,下载安装后几乎不用怎么配置就可以直接使用,而且还支持markd ...
- Android Fragment使用(二) 嵌套Fragments (Nested Fragments) 的使用及常见错误
嵌套Fragment的使用及常见错误 嵌套Fragments (Nested Fragments), 是在Fragment内部又添加Fragment. 使用时, 主要要依靠宿主Fragment的 ge ...
- 推荐一个iOS关于颜色的库-Wonderful
Wonderful 这个库主要是与UIColor息息相连的,其中一共包含四个子文件,UIColor+Wonderful,UIColor+Separate,SXColorGradientView,SXM ...
- reason: '[<__NSDictionary0 0x7fda88f00c90> setValue:forUndefinedKey:]: this class is not key value c
reason: '[<__NSDictionary0 0x7fda88f00c90> setValue:forUndefinedKey:]: this class is not key v ...
- 开始使用 UIAlertController 吧
UIAlertView 与 UIActionSheet UIAlertView 样式 实现 - (void)showAlertView { self.alertView = [[UIAlertView ...
- 浅谈UIAlertController使用
一开始在刚接触到Alert和ActionSheet的时候,经常傻傻分不清楚,好不容易用习惯了,苹果又给合并了,好在用起来也不困难,到底哪个好呢?见仁见智吧! 现在稍微介绍一下怎么用. 1.初始化,一般 ...
- 11-C语言指针&一维数组&字符串
一.用指针遍历数组元素 1.最普通的遍历方式是用数组下标来遍历元素 1 // 定义一个int类型的数组 2 int a[4] = {1, 2, 3, 4}; 3 4 int i; 5 for (i = ...