jQuery.extend({

// 绑定事件
addEvent: function( ele, type, fn ) {

// ele不是DOM,type不是字符串,fn不是函数,打包打走
if( !jQuery.isDOM( ele ) || !jQuery.isString( type ) || !jQuery.isFunction( fn ) ) {
return false;
}

// 兼容处理
if( ele.addEventListener ) {
ele.addEventListener( type, fn );
}else {
ele.attachEvent( 'on' + type, fn );
}
},

// 移除事件
removeEvent: function( ele, type, fn ) {

// ele不是DOM,type不是字符串,fn不是函数,打包打走
if( !jQuery.isDOM( ele ) || !jQuery.isString( type ) || !jQuery.isFunction( fn ) ) {
return false;
}

// 兼容处理
if( ele.removeEventListener ) {
ele.removeEventListener( type, fn );
}else {
ele.detachEvent( 'on' + type, fn );
}
}
});

jQuery.fn.extend({

// 绑定事件
on: function( type, fn ) {
/*
* 实现思路:
* 1、第一次给元素绑定某事件时,给元素按照事件类型初始化一个存储对应事件处理函数的数组
* 2、然后把fn存储进去,再给元素调用addEvent静态方法绑定对应的事件,
* 2.1、这个事件触发时,遍历对应事件处理函数的数组,按照顺序执行他们
* 2.2、同时要改变函数执行时内部的this为绑定者
* 2.3、同时还要把event事件对象传给函数供其使用
* 3、以后再给这个元素绑定已经绑过事件,只需把事件处理函数push到对应的数组中即可。
* 4、链式编程返回this
* */

// 遍历所有元素
return this.each( function() {

var self = this;

// 如果元素之间没有event_cache,那么就初始化一下,有了继续使用之前的。
self.event_cache = self.event_cache || {};

// 判断元素有没有对应事件类型的数组,
// 如果有则直接把fn添加进去即可
if( self.event_cache[ type + '_cache' ] ) {
self.event_cache[ type + '_cache' ].push( fn );
}

// 没有就是第一次绑定该事件
else {

// 先给元素初始化对应的事件数组
self.event_cache[ type + '_cache' ] = [];
self.event_cache[ type + '_cache' ].push( fn );

// 绑定事件,事件触发时,遍历对应的事件数组,执行里面存储的每一个函数
jQuery.addEvent( this, type, function( e ) {

// 遍历对应的事件数组
jQuery.each( self.event_cache[ type + '_cache' ], function() {

// 这里的this指向每一个遍历到的事件处理函数
this.call( self, e );
});
});
}
});
},

// 移除事件
off: function( type, fn ) {
/*
* 实现思路:
* 1、遍历所有元素,如果元素有event_cache再进行下一步处理
* 2、如果没有传参,清空event_cache对象中存储的每一个数组
* 3、如果传了一个参数,清空event_cache对象中指定的数组
* 4、如果传了两个参数,清除event_cache对象中指定数组中指定的函数
* 5、链式编程返回this
* */
var argLen = arguments.length;

return this.each( function() {

var arr = null;
var self = this;

// 如果有event_cache这个对象,说明元素帮过事件,
// 进一步根据参数个数做移除处理。
if( this.event_cache ) {

// 清除所有事件数组
if( argLen === 0 ) {
jQuery.each( this.event_cache, function( key, arr ) {
self.event_cache[ key ] = [];
});
}

// 清除指定的事件数组
else if( argLen === 1 ) {
this.event_cache[ type + '_cache' ] = [];
}

// 清除指定的事件数组中指定的函数
else if( argLen === 2 ) {
arr = this.event_cache[ type + '_cache' ];
for( var i = arr.length - 1; i >= 0; i-- ) {
if( arr[ i ] === fn ) {
arr.splice( i, 1 );
}
}
}
}
});
}
});

// 给原型添加一些事件绑定的简写方式
var events = [ 'click', 'change', 'resize', 'mousedown', 'mouseout', 'mouseenter' ];
jQuery.each( events, function( i, eventName ) {
jQuery.fn[ eventName ] = function( fn ) {
return this.on( eventName, fn );
}
});

jQuery原生框架-----------------事件的更多相关文章

  1. jQuery原生框架-----------------核心框架

    // 1.自调防止全局变量污染(function( window ) { var version = '1.0.0'; var document = window.document; var arr ...

  2. jQuery原生框架中的jQuery.fn.extend和jQuery.extend

    extend 方法在 jQuery 中是一个很重要的方法,jQuey 内部用它来扩展静态方法或实例方法,而且我们开发 jQuery 插件开发的时候也会用到它.但是在内部,是存在 jQuery.fn.e ...

  3. jQuery原生框架-----------------属性操作

    // 添加一个处理兼容获取样式的静态方法jQuery.getStyle = function( dom, styleName ) { // dom不是dom,styleName不是字符串,直接打走 i ...

  4. jQuery原生框架-----------------dom操作

    // 扩展DOM操作方法jQuery.fn.extend({ // 设置或者获取元素的内容 html: function( html ) { /* * 实现思路: * 1.不传参,返回第一个元素的内容 ...

  5. 原生JS事件绑定方法以及jQuery绑定事件方法bind、live、on、delegate的区别

    一.原生JS事件绑定方法: 1.通过HTML属性进行事件处理函数的绑定如: <a href="#" onclick="f()"> 2.通过JavaS ...

  6. 原生js事件和jquery事件的执行顺序问题

    场景:近日,写前端页面时候,在针对输入框input操作时,用到了jquery的插件,插件中使用了jquery的focus()和blur()方法.但是同时,又需要在插件之外再针对输入框的获取焦点和失去焦 ...

  7. Javascript事件模型系列(三)jQuery中的事件监听方式及异同点

    作为全球最知名的js框架之一,jQuery的火热程度堪称无与伦比,简单易学的API再加丰富的插件,几乎是每个前端程序员的必修课.从读<锋利的jQuery>开始,到现在使用jQuery有一年 ...

  8. 原生JavaScript事件详解

    JQuery这种Write Less Do More的框架,用多了难免会对原生js眼高手低. 小菜其实不想写这篇博客,貌似很初级的样子,但是看到网络上连原生js事件绑定和解除都说不明白,还是决定科普一 ...

  9. jQuery验证框架 .

          目录视图 摘要视图 订阅 “程序人生”中国软件开发者职业生涯调查     CSDN社区“三八节”特别活动      开发者职业生涯调查之未来 jQuery验证框架 分类: JQuery 2 ...

随机推荐

  1. 关于GRUB2

    grub2启动引导 GRUB 2是GNU GRUB(GRand Unified Bootloader)的最新版本.bootloader(引导程序)是计算机开机后(bios自检之后)第一个运行的软件程序 ...

  2. AX2012单元格显示颜色 displayOption

    public void displayOption(HV_WMSLocationStatusHistory _record, FormRowDisplayOption _options){    #d ...

  3. CSS样式应用

    CSS样式应用的方法: (1)行内样式,将css样式直接放到标签当中,一般都是放入标签的style属性中,它是最方便的一种样式,也是最不方便修改的样式.如下: (2)内嵌式,通过将css写在网页源文件 ...

  4. 安装MySQL(简便)

    1.在本地虚拟机上上传mysql的5个安装包 2.查看opt目录下是否有这5个安装包 yum install /var/opt/mysql-community-* -y //安装MySQL syste ...

  5. Java集合——ConcurrentHashMap

    集合是编程中最常用的数据结构.而谈到并发,几乎总是离不开集合这类高级数据结构的支持.比如两个线程需要同时访问一个中间临界区(Queue),比如常会用缓存作为外部文件的副本(HashMap).这篇文章主 ...

  6. Task

    .net 4.0为我们带来了TPL(Task Parallel Library),其中Task相较ThreadPool线程池使用更简单,而且支持线程的取消,完成和失败通知等交互性操作,而这些是Thre ...

  7. 打造最高效的科研环境之Emacs插件们

    0 盲人摸象 作为初学者,迫切的需求就是直接上手Emacs并打造包含自动补全命令在内的科研环境. 和网上众多的插件安装的教程相比,我认为找到一个与自己需求匹配的Emacs配置环境来得更方便. 本例中, ...

  8. MYSQL数据库日志和mysqlbinlog相关

    mysql有4种不同的日志,分别是二进制日志,查询日志,慢查询日志和错误日志,这些日记记录着数据库工作的方方面面,可以帮助我们了解数据库的不同方面的踪迹,下面介绍二进制日志的作用和使用方法. 1.二进 ...

  9. POJ 3176 Cow Bowling

    Cow Bowling Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 13016   Accepted: 8598 Desc ...

  10. C#简易一元二次求解器

    using System;using System.Collections.Generic;using System.ComponentModel;using System.Data;using Sy ...