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. contiki-定时器etimer

    Contiki内核是基于事件驱动和Protothreads机制,事件既可以是外部事件(比如按键,数据到达),也可以是内部事件(如时钟中断).定时器的重要性不言而喻,Contiki提供了5种定时器模型, ...

  2. union内嵌struct用法

      // union内嵌struct用法 // 众所周知,union为联合体,struct为结构体.下面根据实例谈谈用法   #include <stdio.h>   #include & ...

  3. 如何让nginx显示文件夹目录

    1. 如何让nginx显示文件夹目录 vi /etc/nginx/conf.d/default.conf 添加如下内容: location / {           root /data/www/f ...

  4. Yii 读取CVS文件内容插入到数据库

    这个方法和上次写的读取txt文件的方法基本上差不多,直接贴代码,需要的直接拿走 function ImportExcel(){ $file = fopen('test.csv','r'); //输出文 ...

  5. ASP.NET MVC简介

    MVC全名是Model View Controller,是模型(model)-视图(view)-控制器(controller)的缩写,一种软件设计典范,用一种业务逻辑.数据.界面显示分离的方法组织代码 ...

  6. 《Linux内核设计与实现》课本第三章自学笔记——20135203齐岳

    <Linux内核设计与实现>课本第三章自学笔记 进程管理 By20135203齐岳 进程 进程:处于执行期的程序.包括代码段和打开的文件.挂起的信号.内核内部数据.处理器状态一个或多个具有 ...

  7. windows下登录lunix服务器

    在微信项目中,负责发布,我就把我用到的记录一下.有两种登录方式,看你要做什么操作. 1.SecureCRT 支持命令行操作.(主要是发布程序) 调试.微信公众号规定要有服务器的网址,一般公司的都是内网 ...

  8. how to get soul shields in blade and soul

    These soul shields can either be obtained by E.Fleet Supply Chain or Blackram Supply Chain (4-man or ...

  9. Java面试常见各种概念区别比较

    Hashtable 和 HashMap之间的区别 Hashtable是继承了Dictionary,是线程安全的.HashMap实现了Map接口,不是线程安全的.HashMap是Hashtable的轻量 ...

  10. 荣品RP4412开发板烧写内核cannot load出错的原因

    问:荣品RP4412开发板烧写必须要配置Xmanager吗? 现在我烧写内核出现这个错误是什么原因呢? 答:4412文件夹下没有zImage这个文件, 你打开4412这个文件夹. 你都拼写错了, zI ...