这里主要分析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)的更多相关文章

  1. zepto 事件分析1($.Event)

    先看一下zepto事件的函数,在这里,zepto是把zepto对象作为一个立即执行函数的参数传进去的. (function($){ ... ... })(Zepto) 在zepto事件函数中,主要为$ ...

  2. zepto 事件分析4(事件队列)

    前面分析了zepto的事件绑定,接下来分析事件解绑,先看一下zepto中解绑的off方法: $.fn.off = function(event, selector, callback){ var $t ...

  3. zepto 事件分析3(add函数)

    在上一篇的分析中,最后$.on方法返回了一个add方法函数的执行,在这里先看一下其代码: function add(element, events, fn, data, selector, deleg ...

  4. Zepto事件模块源码分析

    Zepto事件模块源码分析 一.保存事件数据的handlers 我们知道js原生api中要移除事件,需要传入绑定时的回调函数.而Zepto则可以不传入回调函数,直接移除对应类型的所有事件.原因就在于Z ...

  5. 移动web app开发必备 - zepto事件问题

    问题描述: 项目在祖先元素上绑定了 touchstart,touchmove,touchend事件,用来处理全局性的事件,比如滑动翻页 正常状态下: 用户在子元素上有交互动作时,默认状态下都是会冒泡到 ...

  6. OneAlert 入门(三)——事件分析

    OneAlert 是国内首个 SaaS 模式的云告警平台,集成国内外主流监控/支撑系统,实现一个平台上集中处理所有 IT 事件,提升 IT 可靠性.有了 OneAlert,你可以更快更合理地为事件划分 ...

  7. OneAlert 入门(二)——事件分析

    OneAlert 是国内首个 SaaS 模式的云告警平台,集成国内外主流监控/支撑系统,实现一个平台上集中处理所有 IT 事件,提升 IT 可靠性.有了 OneAlert,你可以更快更合理地为事件划分 ...

  8. 跨浏览器resize事件分析

    resize事件 原生事件分析 window一次resize事件: IE7 触发3次, IE8 触发2次, IE9 触发1次, IE10 触发1次 Chrome 触发1次 FF 触发2次 Opera ...

  9. GridView事件分析

    GridView事件分析 (转) P1默认数据绑定过程 编号 事件名称 作用 E1 DataBinding 数据绑定之前触发,在这个事件之前(第一次生成GridView),GridView不存在行数据 ...

随机推荐

  1. js打断点

    F12打开调试器         资源sources     找到就是文件    选中需要打断点的行 获得段短点的值:将断点向后执行一步(页面提示的桥状小图标),然后选中上一步需要打断点的值,悬浮在上 ...

  2. gitlab 之 项目管理

    首先git是什么? Git是一款免费.开源的分布式版本控制系统,用于敏捷高效地处理任何或小或大的项目.Git的读音为/gɪt/. Git是一个开源的分布式版本控制系统,可以有效.高速的处理从很小到非常 ...

  3. hive -help hive命令行执行sql参数

    在shell命令行执行 hive -help 结果如下: -d,--define <key=value> Variable substitution to apply to Hive co ...

  4. C++ 使用Lambda

    基础使用: C++中的Lambda表达式详解 c++11的闭包(lambda.function.bind) C++ lambda作为函数参数,实现通用的查找接口 C++11系列-lambda函数 进阶 ...

  5. 用python处理csv文件

    1.准备csv文件(这里是平安银行的统计表:下载并另存为pingan.csv) >>> from urllib import urlretrieve >>> url ...

  6. weexpack打包weex项目运行/打包记录

    构建weex项目 安装weex-toolkit cnpm install -g weex-toolkit 初始化一个项目只需新建文件夹并在目录下执行 weex init 即可 安装依赖:cnpm in ...

  7. Android NDK学习(一):目录结构解析

    我们配置好NDK环境后,基本可以看到其目录结构如下图: 下面我们来分析一下NDK根目录的结构: ndk-build:该Shell脚本是Android NDK构建系统的起始点,一般在项目中仅仅执行这一个 ...

  8. 每天学点SpringCloud(九):SpringCloud最常用配置详解

    Eureka 属性名 说明 默认值 eureka.server.enable-self-preservation 关闭注册中心的保护机制,Eureka 会统计15分钟之内心跳失败的比例低于85%将会触 ...

  9. 纯小白创建第一个Node程序失败-容易忽略的一个细节

    一直觉得自己基础还很差,所以自觉不敢去碰node.js,但又对其心怀好奇.恰巧最近有一点空闲时间,忍不住去试了一下水   这不,在创建第一个node程序时就吃了闭门羹,总是提示我没有定义,如下图, 这 ...

  10. silverlight属性改变事件通知

    工作中遇到silverlight本身没有提供的某些属性改变事件,但又需要在属性改变时得到通知,Google搬运stack overflow,原地址 /// Listen for change of t ...