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不存在行数据 ...
随机推荐
- Java程序CPU使用率过高
Java程序CPU使用率过高 通过top命令找到使用率过高的java进程PID 根据进程号查找线程TID:ps -mp PID -o THREAD,tid,time 将TID转换成16进制:print ...
- 二叉树遍历之三(Moriis traversal)
二叉树的Morris traversal是个很值得学习的算法,也是此系列重点想要记叙的一个算法.Morris traversal的一个亮点在于它是O(1)空间复杂度的.前面的递归和迭代都是需要O(n ...
- weblogic.xml 精妙设置
1.一:weblogic 页面访问速度比tomcat慢的原因和解决办法 一:weblogic 页面访问速度比tomcat慢的原因和解决办法 公司有个项目,部署在weblogic8.1上之后,发现比在t ...
- Android 基本控件相关知识整理
Android应用开发的一项重要内容就是界面开发.对于用户来说,不管APP包含的逻辑多么复杂,功能多么强大,如果没有提供友好的图形交互界面,将很难吸引最终用户.作为一个程序员如何才能开发出友好的图形界 ...
- python写的翻译代码
# -*- coding: utf-8 -*- from Tkinter import *import difflibimport urllib2import urllib # python2.7才需 ...
- redis订阅关闭异常解决
redis订阅关闭异常解决 应用程序模块订阅redis运行一段时间出现一直重连Redis服务,日志如下: 2019-04-28 10:06:17,551 ERROR org.springframewo ...
- 《http权威指南》读书笔记18
概述 最近对http很感兴趣,于是开始看<http权威指南>.别人都说这本书有点老了,而且内容太多.我个人觉得这本书写的太好了,非常长知识,让你知道关于http的很多概念,不仅告诉你怎么做 ...
- RISC-V平台的汇编指令解析
csrr a0, 0xF14 //把0xF14的值读入到a0中 andi a1, a0, 0x1f //把a0 和0x1F按位与运算后存储到a1中 srli a0, a0, 5 ...
- Liunx服务管理(Centos)
RPM包安装的服务其安装文件是遵循系统默认安装位置,所以可以通过命令快速启动,但源码包的安装是统一放在一个自定义文件夹下,所有其服务要使用绝对路径,但也可以通过软连接方式,让其支持RPM包相同管理方式 ...
- 树莓派连接不上WiFi
之前还好好的,突然连接不上WiFi,打开文件WiFi配置文件:/etc/wpa_supplicant/wpa_supplicant.conf发现有多个连接记录,把用到的留下,其他的删掉即可: sudo ...