博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
zepto 事件分析2($.on)
阅读量:6088 次
发布时间:2019-06-20

本文共 3835 字,大约阅读时间需要 12 分钟。

这里主要分析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在事件流的捕获,目标及冒泡阶段。

1`

当我们点击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()函数,该函数留在下一篇分析。

 

转载于:https://www.cnblogs.com/Darlietoothpaste/p/6613720.html

你可能感兴趣的文章
oracle ORA-01840:输入值对于日期格式不够长
查看>>
python基础知识~logger模块
查看>>
SIP入门(二):建立SIPserver
查看>>
Servlet3.0的异步
查看>>
WebService连接postgresql( 失败尝试)
查看>>
从头认识java-13.11 对照数组与泛型容器,观察类型擦除给泛型容器带来什么问题?...
查看>>
Python-MacOSX下SIP引起的pip权限问题解决方案(非取消SIP机制)
查看>>
从MFQ方法到需求分析
查看>>
android.view.WindowManager$BadTokenException: Unable to add window
查看>>
HDU5012:Dice(bfs模板)
查看>>
iphone openssh
查看>>
Linux下MEncoder的编译
查看>>
spark高级排序彻底解秘
查看>>
ylbtech-LanguageSamples-PartialTypes(部分类型)
查看>>
福建省促进大数据发展:变分散式管理为统筹集中式管理
查看>>
开发环境、生产环境、测试环境的基本理解和区别
查看>>
tomcat多应用之间如何共享jar
查看>>
Flex前后台交互,service层调用后台服务的简单封装
查看>>
MySQL入门12-数据类型
查看>>
Windows Azure 保留已存在的虚拟网络外网IP(云服务)
查看>>