这里主要分析zepto事件中的$.on函数,先看一下该函数的代码

  1. $.fn.on = function(event, selector, data, callback, one){
  2. var autoRemove, delegator, $this = this
  3. if (event && !isString(event)) {
  4. //多个事件下的处理
  5. $.each(event, function(type, fn){
  6. $this.on(type, selector, data, fn, one)
  7. })
  8. return $this
  9. }
  10. //根据传入的参数初始化各个参数
  11. //(event,data,callback)
  12. if (!isString(selector) && !isFunction(callback) && callback !== false)
  13. callback = data, data = selector, selector = undefined
  14. //(event,selector,callback)
  15. if (callback === undefined || data === false)
  16. callback = data, data = undefined
  17. //callback = function(){return false}
  18. if (callback === false) callback = returnFalse
  19. //迭代zepto对象中的元素
  20. return $this.each(function(_, element){
  21. if (one) autoRemove = function(e){
  22. remove(element, e.type, callback)
  23. return callback.apply(this, arguments)
  24. }
  25. //如果有传入选择器 定义一个delegator函数
  26. if (selector) delegator = function(e){
  27. //从触发事件目标出发找寻符合selector选择器的元素
  28. var evt, match = $(e.target).closest(selector, element).get(0)
  29. //如果存在并且不是element
  30. if (match && match !== element) {
  31. //对event对象进行转化操作
  32. evt = $.extend(createProxy(e), {currentTarget: match, liveFired: element})
  33. return (autoRemove || callback).apply(match, [evt].concat(slice.call(arguments, 1)))
  34. }
  35. }
  36. add(element, event, callback, data, selector, delegator || autoRemove)
  37. })
  38. }

该函数主要分析的是return 后面的语句,在前面的分析中,分析了each函数和$对象,也就是对$对象中的每一个dom进行绑定事件,这里先跳过autoRemove函数,留在后面分析,如果有传入选择器,zepto先定义一个delegator函数,delegator函数中有一个match变量,该变量即为我们要绑定事件的目标元素,zepto采用的是事件委托,官方文档对于closest的定义如下:

而e.target即是事件触发的元素,注意:currentTarget和e.target是不同的。target在事件流的目标阶段;currentTarget在事件流的捕获,目标及冒泡阶段。

  1. <body>
  2. <div class="out">
  3. <div class="in"><h2>1`</h2></div>
  4. </div>
  5. </html>
  6. <script type="text/javascript">
  7.  
  8. function test2(e){
  9. console.log(e.target);
  10. console.log(e.currentTarget)
  11. };
  12. var box2 = document.getElementsByClassName('in')[0];
  13. box2.addEventListener("click",test2);

当我们点击h2时,target指向<h2>,currentTarget指向<div class='in'>;

在获得match之后,判断其是否存在或是否为元素本身,如果是,则什么都不做,如果不是,则创建一个新的事件evt,并将原来的事件属性赋值给evt,并改变currentTarget和 liveFired的属性值。

其中有一个createProxy函数,该函数的功能即为复制属性。

  1. function createProxy(event) {
  2. var key, proxy = { originalEvent: event }
  3. for (key in event)
  4. if (!ignoreProperties.test(key) && event[key] !== undefined) proxy[key] = event[key]
  5.  
  6. return compatible(proxy, event)
  7. }

createProxy函数最后返回的是一个compatible函数的执行,在之前分析$.Event就有遇到过,在这里来分析其作用。

  1. function compatible(event, source) {
    //如果没有传入source函数并且evnet事件阻止了默认操作,则直接返回传入的event参数
  2. if (source || !event.isDefaultPrevented) {
  3. source || (source = event)
  4.  
  5. $.each(eventMethods, function(name, predicate) {
  6. var sourceMethod = source[name]
  7. event[name] = function(){
  8. this[predicate] = returnTrue
  9. return sourceMethod && sourceMethod.apply(source, arguments)
  10. }
  11. event[predicate] = returnFalse
  12. })
  13.  
  14. event.timeStamp || (event.timeStamp = Date.now())
  15. //对其默认操作进行相关判断
  16. if (source.defaultPrevented !== undefined ? source.defaultPrevented :
  17. 'returnValue' in source ? source.returnValue === false :
  18. source.getPreventDefault && source.getPreventDefault())
  19. event.isDefaultPrevented = returnTrue
  20. }
  21. return event
  22. }

该函数最主要的代码在中间的$.each(...),可以先看一下eventMethods的定义

  1. eventMethods = {
  2. preventDefault: 'isDefaultPrevented',
  3. stopImmediatePropagation: 'isImmediatePropagationStopped',
  4. stopPropagation: 'isPropagationStopped'
  5. }

在原生的事件属性中,也存在prereventDefault等方法以及判断其值的defaultPrevented属性,但在zepto中,每次绑定事件,实际上都相当于重新定义一个事件,而自我定义的属性是不具备prereventDefault等方法的功能,那么defaultPrevented的值也就失效了。如图:

  1. function test2(e){
  2. var evt = {};
  3. for(key in evt)
  4. evt[key] = e[key];
  5. evt.preventDefault();
  6. };
  7. var box2 = document.getElementsByClassName('in')[0];
  8. 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. 你可能不知道的web api

    简介 作为前端工作者,我们的工作与web是分不开的,随着HTML5的日益壮大,浏览器自带的webapi也随着增多.本篇文章主要选取了几个有趣且有用的webapi进行介绍,分别介绍其用法.用处以及浏览器 ...

  2. 【repost】让你一句话理解闭包(简单易懂)

    接触javascript很久了,每次理解闭包都似是而非,最近在找Web前端的工作,所以需要把基础夯实一下. 本文是参照了joy_lee的博客 闭包 在她这篇博客的基础上以批注的形式力争把我的理解阐述出 ...

  3. IDEA打开maven项目dependencies红线

    第一步:install报红的项目,从maven库下载需要的包,看看日志还缺哪些本地包,少了就去下,丢到库里.不缺包后,reimport一下一般就OK了,如果还是红的,重启一下就好了. 如果第一步还没好 ...

  4. some knowledge of the IT world

    IT世界一切皆是可信息化(数据的转换)即信息记录一切,对信息的控制{存储,运算,传输{信息的位置转移},转换}就是对一切的控制{硬件(实质维)以信息的控制{软件形式(存在维)}进行操作} 信息本身的实 ...

  5. Redis-01.初探

    官网 http://redis.io 中文网 http://redis.cn 命令参考 http://redisdoc.cn Redis(Remote Dictionary Server)是一个开源的 ...

  6. 利用WindowsServiceWrapper(WinSW)将nginx包装为系统服务

    1.WindowsServiceWrapper(WinSW) Github:https://github.com/kohsuke/winsw/ 下载地址:http://repo.jenkins-ci. ...

  7. 自定义滚动条样式(layui.v1)

    来源于 layui css 代码 ::-webkit-scrollbar { width: 10px; height: 10px; } ::-webkit-scrollbar-button, ::-w ...

  8. Git使用详细教程(1):工作区、暂存区、本地仓库、远程仓库

    之前的写过一篇如何在服务器上搭建Git服务Git服务器搭建,接下来的一段时间,我将详细的讲解Git的使用.看如下一张图片,本篇主要理解一些基本概念. 图中几个名词的意思如下: workspace: 工 ...

  9. 第86节:Java中的JQuery基础

    第86节:Java中的JQuery 前言复习 定时器: setInterval clearInterval setTimeout clearTimeout 显示: img.style.display ...

  10. 【MySQL】存储emoji表情报错(Incorrect string value: '\xF0\x9F\x98\x82\xF0\x9F...')的解决方案

    Emoji表情字符现在在APP已经广泛支持了.但是MySQL的UTF8编码对Emoji字符的支持却不是那么好.所以我们经常会遇到这样的异常:   Java.sql.SQLException: Inco ...