zepto 事件分析2($.on)
这里主要分析zepto事件中的$.on函数,先看一下该函数的代码
$.fn.on = function(event, selector, data, callback, one){
var autoRemove, delegator, $this = this
if (event && !isString(event)) {
//多个事件下的处理
$.each(event, function(type, fn){
$this.on(type, selector, data, fn, one)
})
return $this
}
//根据传入的参数初始化各个参数
//(event,data,callback)
if (!isString(selector) && !isFunction(callback) && callback !== false)
callback = data, data = selector, selector = undefined
//(event,selector,callback)
if (callback === undefined || data === false)
callback = data, data = undefined
//callback = function(){return false}
if (callback === false) callback = returnFalse
//迭代zepto对象中的元素
return $this.each(function(_, element){
if (one) autoRemove = function(e){
remove(element, e.type, callback)
return callback.apply(this, arguments)
}
//如果有传入选择器 定义一个delegator函数
if (selector) delegator = function(e){
//从触发事件目标出发找寻符合selector选择器的元素
var evt, match = $(e.target).closest(selector, element).get(0)
//如果存在并且不是element
if (match && match !== element) {
//对event对象进行转化操作
evt = $.extend(createProxy(e), {currentTarget: match, liveFired: element})
return (autoRemove || callback).apply(match, [evt].concat(slice.call(arguments, 1)))
}
}
add(element, event, callback, data, selector, delegator || autoRemove)
})
}
该函数主要分析的是return 后面的语句,在前面的分析中,分析了each函数和$对象,也就是对$对象中的每一个dom进行绑定事件,这里先跳过autoRemove函数,留在后面分析,如果有传入选择器,zepto先定义一个delegator函数,delegator函数中有一个match变量,该变量即为我们要绑定事件的目标元素,zepto采用的是事件委托,官方文档对于closest的定义如下:

而e.target即是事件触发的元素,注意:currentTarget和e.target是不同的。target在事件流的目标阶段;currentTarget在事件流的捕获,目标及冒泡阶段。
<body>
<div class="out">
<div class="in"><h2>1`</h2></div>
</div>
</html>
<script type="text/javascript"> function test2(e){
console.log(e.target);
console.log(e.currentTarget)
};
var box2 = document.getElementsByClassName('in')[0];
box2.addEventListener("click",test2);
当我们点击h2时,target指向<h2>,currentTarget指向<div class='in'>;
在获得match之后,判断其是否存在或是否为元素本身,如果是,则什么都不做,如果不是,则创建一个新的事件evt,并将原来的事件属性赋值给evt,并改变currentTarget和 liveFired的属性值。
其中有一个createProxy函数,该函数的功能即为复制属性。
function createProxy(event) {
var key, proxy = { originalEvent: event }
for (key in event)
if (!ignoreProperties.test(key) && event[key] !== undefined) proxy[key] = event[key]
return compatible(proxy, event)
}
createProxy函数最后返回的是一个compatible函数的执行,在之前分析$.Event就有遇到过,在这里来分析其作用。
function compatible(event, source) {
//如果没有传入source函数并且evnet事件阻止了默认操作,则直接返回传入的event参数
if (source || !event.isDefaultPrevented) {
source || (source = event)
$.each(eventMethods, function(name, predicate) {
var sourceMethod = source[name]
event[name] = function(){
this[predicate] = returnTrue
return sourceMethod && sourceMethod.apply(source, arguments)
}
event[predicate] = returnFalse
})
event.timeStamp || (event.timeStamp = Date.now())
//对其默认操作进行相关判断
if (source.defaultPrevented !== undefined ? source.defaultPrevented :
'returnValue' in source ? source.returnValue === false :
source.getPreventDefault && source.getPreventDefault())
event.isDefaultPrevented = returnTrue
}
return event
}
该函数最主要的代码在中间的$.each(...),可以先看一下eventMethods的定义
eventMethods = {
preventDefault: 'isDefaultPrevented',
stopImmediatePropagation: 'isImmediatePropagationStopped',
stopPropagation: 'isPropagationStopped'
}
在原生的事件属性中,也存在prereventDefault等方法以及判断其值的defaultPrevented属性,但在zepto中,每次绑定事件,实际上都相当于重新定义一个事件,而自我定义的属性是不具备prereventDefault等方法的功能,那么defaultPrevented的值也就失效了。如图:
function test2(e){
var evt = {};
for(key in evt)
evt[key] = e[key];
evt.preventDefault();
};
var box2 = document.getElementsByClassName('in')[0];
box2.addEventListener("click",test2);

所以compatible函数的作用就是为了使原生事件preventDefault等的方法以及判断其值的属性转变为一个方法来使用。
在delegator函数中,最后返回的是对绑定函数的执行。
最后on方法执行了一个add()函数,该函数留在下一篇分析。
zepto 事件分析2($.on)的更多相关文章
- zepto 事件分析1($.Event)
先看一下zepto事件的函数,在这里,zepto是把zepto对象作为一个立即执行函数的参数传进去的. (function($){ ... ... })(Zepto) 在zepto事件函数中,主要为$ ...
- zepto 事件分析4(事件队列)
前面分析了zepto的事件绑定,接下来分析事件解绑,先看一下zepto中解绑的off方法: $.fn.off = function(event, selector, callback){ var $t ...
- 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不存在行数据 ...
随机推荐
- How Does Closure Work in Javascript?
Simply, closure is the scope that it can visite and operate the variables outside of the function wh ...
- bzoj1031(sa)
省选前练习模板系列: #include<iostream> #include<cstdio> #include<cmath> #include<cstring ...
- Nginx 教程(2):性能
tcp_nodelay, tcp_nopush 和 sendfile tcp_nodelay 在 TCP 发展早期,工程师需要面对流量冲突和堵塞的问题,其中涌现了大批的解决方案,其中之一是由 John ...
- Android中监控USB的插拔
一.需求 在Android应该开发过程中,用到了USB通讯,需要应用监控USB设备的插入和拔出,从而刷新USB设备列表. 二.实现 在使用时,需要register和unregister. 通过UsbD ...
- centos 7 默认图形界面(或者字符界面)启动
1.切换到管理员用户 2.systemctl get-default命令获取当前模式(可以省去) 3.systemctl set-default graphical.target 修改启动模式(修改为 ...
- 关于Nginx设置端口号,在Asp.net 获取不到的,解决办法
不知道你有没有遇到过这样的问题,网站访客多起来后,心里很是高兴,加上了Nginx反向代理,出问题了 原来是这么写的: Request.Url.ToString() 输出是这样的: http://www ...
- ES6之命令妙用
很多人都听说过ES6(也就是ECMAScript的新一代标准)并且对她充满了向往,下面通过一个ES6中小知识点——let命令,来解开她的神秘面纱,让大家初步认识一下ES6的语法规范. ...
- Android 代码混淆配置总结
一.前言 为何需要混淆呢?简单的说,就是将原本正常的项目文件,对其类,方法,字段,重新命名,a,b,c,d,e,f…之类的字母,达到混淆代码的目的,这样反编译出来,结构乱糟糟的,看了也头大. 另外说明 ...
- Python学习笔记【第十四篇】:Python网络编程二黏包问题、socketserver、验证合法性
TCP/IP网络通讯粘包问题 案例:模拟执行shell命令,服务器返回相应的类容.发送指令的客户端容错率暂无考虑,按照正确的指令发送即可. 服务端代码 # -*- coding: utf- -*- # ...
- Linux 总是提示You have new mail in /var/spool/mail/root
解决办法: echo “unset MAILCHECK” >> /etc/profile source /etc/profile 这样就可以了!!!!!!!!!!