zepto 事件分析4(事件队列)
前面分析了zepto的事件绑定,接下来分析事件解绑,先看一下zepto中解绑的off方法:
$.fn.off = function(event, selector, callback){
var $this = this
if (event && !isString(event)) {
$.each(event, function(type, fn){
$this.off(type, selector, fn)
})
return $this
} if (!isString(selector) && !isFunction(callback) && callback !== false)
callback = selector, selector = undefined if (callback === false) callback = returnFalse return $this.each(function(){
remove(this, event, callback, selector)
})
}
offf方法前面大致和on方法一样,最主要的是最后return里面的remove函数,在看remove之前,要先分析之前遇到的有关handler的函数,下面是在add方法中,关于handler的。
function add(element, events, fn, data, selector, delegator, capture){
var id = zid(element), set = (handlers[id] || (handlers[id] = []))
events.split(/\s/).forEach(function(event){
...
var handler = parse(event)
handler.fn = fn
handler.sel = selector
console.log(handler.e)
// emulate mouseenter, mouseleave
if (handler.e in hover) fn = function(e){
...
}
handler.del = delegator
var callback = delegator || fn
handler.proxy = function(e){
...
...
}
handler.i = set.length
set.push(handler)
if ('addEventListener' in element)
element.addEventListener(realEvent(handler.e), handler.proxy, eventCapture(handler, capture))
})
}
首先通过zid函数设置一个id,并获得hanlders[id]数组,这里面使用了闭包的功能,在整个事件函数中定义了handlers和_zid两个变量,并在内部函数中采用函数的方式返回,使其不被回收。每个元素都有一个id,该id可以在handlers里面找到自己的事件队列。
var _zid = 1,handlers = {};
function zid(element) {
return element._zid || (element._zid = _zid++)
};
function add(...){
var id = zid(element), set = (handlers[id] || (handlers[id] = []));
...
};
$(".out").on('click',function(event) {
console.log($(this))
event.stopPropagation();
});
$(".in").on('click',function(event) {
console.log($(this))
});
接下来,add函数定义了一个handler变量。该变量通过将event作为参数传入parse函数获得。
function parse(event) {
var parts = ('' + event).split('.')
//返回一个对象,e为事件的type属性,ns为事件的命名空间
return {e: parts[0], ns: parts.slice(1).sort().join(' ')}
}
接下来,将事件的一系列相关参数放入handler里面,最后设置handler.i为set的长度(作为handler事件的一个index),并将handler放进set,也就是放进handlers[id]。
也就是说,像上面的例子定义之后,handlers里面是这样的(每一个属性代表一个元素里面的事件队列,如1是对应的数组是div.in的事件队列)。
分析handlers相关之后,就可以看remove函数了:
function remove(element, events, fn, selector, capture){
//获得元素在handlers中的对应id
var id = zid(element)
//遍历定义的事件
;(events || '').split(/\s/).forEach(function(event){
findHandlers(element, event, fn, selector).forEach(function(handler){
delete handlers[id][handler.i]
if ('removeEventListener' in element)
element.removeEventListener(realEvent(handler.e), handler.proxy, eventCapture(handler, capture))
})
})
}
function findHandlers(element, event, fn, selector) {
event = parse(event)
if (event.ns) var matcher = matcherFor(event.ns)
return (handlers[zid(element)] || []).filter(function(handler) {
return handler
&& (!event.e || handler.e == event.e)
&& (!event.ns || matcher.test(handler.ns))
&& (!fn || zid(handler.fn) === zid(fn))
&& (!selector || handler.sel == selector)
})
}
首先通过finHandlers函数来查询符合的事件,该函数相对简单,通过filter来返回一个符合条件的事件数组,接下来通过delete语句删除handlers[id]中对应的handler,并使用原生的解绑事件解绑。
那么整个事件队列的分析就结束了,之前在分析$.on函数时,也有一个remove没有分析。
$.fn.on = function(event, selector, data, callback, one){
...
return $this.each(function(_, element){
if (one) autoRemove = function(e){
remove(element, e.type, callback)
return callback.apply(this, arguments)
}
...
add(element, event, callback, data, selector, delegator || autoRemove)
})
}
如果传入了one参数,那么就定义一个autoRemove函数,内部调用remove解绑,并返回绑定事件的执行。这样就保证了只执行一次。
zepto 事件分析4(事件队列)的更多相关文章
- zepto 事件分析2($.on)
这里主要分析zepto事件中的$.on函数,先看一下该函数的代码 $.fn.on = function(event, selector, data, callback, one){ var autoR ...
- zepto 事件分析1($.Event)
先看一下zepto事件的函数,在这里,zepto是把zepto对象作为一个立即执行函数的参数传进去的. (function($){ ... ... })(Zepto) 在zepto事件函数中,主要为$ ...
- zepto 事件分析3(add函数)
在上一篇的分析中,最后$.on方法返回了一个add方法函数的执行,在这里先看一下其代码: function add(element, events, fn, data, selector, deleg ...
- Zepto事件模块源码分析
Zepto事件模块源码分析 一.保存事件数据的handlers 我们知道js原生api中要移除事件,需要传入绑定时的回调函数.而Zepto则可以不传入回调函数,直接移除对应类型的所有事件.原因就在于Z ...
- 移动web app开发必备 - zepto事件问题
问题描述: 项目在祖先元素上绑定了 touchstart,touchmove,touchend事件,用来处理全局性的事件,比如滑动翻页 正常状态下: 用户在子元素上有交互动作时,默认状态下都是会冒泡到 ...
- OneAlert 入门(三)——事件分析
OneAlert 是国内首个 SaaS 模式的云告警平台,集成国内外主流监控/支撑系统,实现一个平台上集中处理所有 IT 事件,提升 IT 可靠性.有了 OneAlert,你可以更快更合理地为事件划分 ...
- OneAlert 入门(二)——事件分析
OneAlert 是国内首个 SaaS 模式的云告警平台,集成国内外主流监控/支撑系统,实现一个平台上集中处理所有 IT 事件,提升 IT 可靠性.有了 OneAlert,你可以更快更合理地为事件划分 ...
- 跨浏览器resize事件分析
resize事件 原生事件分析 window一次resize事件: IE7 触发3次, IE8 触发2次, IE9 触发1次, IE10 触发1次 Chrome 触发1次 FF 触发2次 Opera ...
- GridView事件分析
GridView事件分析 (转) P1默认数据绑定过程 编号 事件名称 作用 E1 DataBinding 数据绑定之前触发,在这个事件之前(第一次生成GridView),GridView不存在行数据 ...
随机推荐
- 3、MHC主要组织相容性复合体
主要组织相容性复合体 (major histocompatibility complex MHC) 位于脊椎动物某对染色体上紧密连锁的基因群,其编码的蛋白是主要组织相容性抗原,是移植排斥反应的主要抗原 ...
- [转]Java工程师技术栈--成神之路
一.基础篇 1.1 JVM 1.1.1. Java内存模型,Java内存管理,Java堆和栈,垃圾回收 http://www.jcp.org/en/jsr/detail?id=133http://if ...
- python 中爬虫 content和text的区别
一直在想requests的content和text属性的区别,从print 结果来看是没有任何区别 import requests headers = { "User-Agent" ...
- Cookie的几点忠告
1.不要在COOKIE中保存明文的敏感信息 2.不要在COOKIE中保存永久的敏感信息,即每个COOKIE 都需要有时效性,过期则失效. 参考 XSS跨站攻击相关资料 http://www.cnblo ...
- Office Web addin 踩坑计:替换后台网站为MVC框架时遇到的问题
Office Web Addin 模板程序的后台本质上是一个网站,你在调试的时候可以发现它的进程是一个32位的IE进程 所以可以把它替换成Asp.net的网站. 替换方法: 1.点击WordRevie ...
- Python学习过程中各个难点---函数篇
对于函数,我一直分不清局部变量与全局变量,今天又好好研究了下,终于搞清楚了. 例子: 其次对于global这个关键字我也是一知半解的状态,之前整个人都是懵懵的,现在搞明白了 匿名函数: 匿名函数使用关 ...
- CentOS5.5 - lnmp环境安装与使用
CentOS5.5 - lnmp环境安装与使用 到公司搭建环境可以直接使用YUM. 安装一.rpm包安装(安装方便) yum:下载软件包并且安装.前提:连网. yum 使用流程: 1. yum lis ...
- [转]Comparing sFlow and NetFlow in a vSwitch
As virtualization shifts the network edge from top of rack switches to software virtual switches run ...
- Asp.Net WebApi核心对象解析(二)
在接着写Asp.Net WebApi核心对象解析(下篇)之前,还是一如既往的扯扯淡,元旦刚过,整个人还是处于晕的状态,一大早就来处理系统BUG,简直是坑爹(好在没让我元旦赶过来该BUG),队友挖的坑, ...
- 基于Fusioncharts的报表统计
先了解fusioncharts插件,fusioncharts是一款基于XML和flash的报表组件,支持Java.PHP.AngularJS等等开发语言,所以,开发出来,加入swf文件,就可以出现动态 ...