博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
zepto 事件分析4(事件队列)
阅读量:6354 次
发布时间:2019-06-22

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

前面分析了zepto的事件绑定,接下来分析事件解绑,先看一下zepto中解绑的off方法:

$.fn.off = function(event, selector, callback){    var $this = this    if (event && !isString(event)) {      $.each(event, function(type, fn){        $this.off(type, selector, fn)      })      return $this    }    if (!isString(selector) && !isFunction(callback) && callback !== false)      callback = selector, selector = undefined    if (callback === false) callback = returnFalse    return $this.each(function(){      remove(this, event, callback, selector)    })  }

offf方法前面大致和on方法一样,最主要的是最后return里面的remove函数,在看remove之前,要先分析之前遇到的有关handler的函数,下面是在add方法中,关于handler的。

function add(element, events, fn, data, selector, delegator, capture){    var id = zid(element), set = (handlers[id] || (handlers[id] = []))    events.split(/\s/).forEach(function(event){     ...      var handler   = parse(event)      handler.fn    = fn      handler.sel   = selector      console.log(handler.e)      // emulate mouseenter, mouseleave      if (handler.e in hover) fn = function(e){      ...      }      handler.del   = delegator      var callback  = delegator || fn      handler.proxy = function(e){       ...       ...      }      handler.i = set.length      set.push(handler)      if ('addEventListener' in element)        element.addEventListener(realEvent(handler.e), handler.proxy, eventCapture(handler, capture))    })  }

首先通过zid函数设置一个id,并获得hanlders[id]数组,这里面使用了闭包的功能,在整个事件函数中定义了handlers和_zid两个变量,并在内部函数中采用函数的方式返回,使其不被回收。每个元素都有一个id,该id可以在handlers里面找到自己的事件队列。

var _zid = 1,handlers = {};function zid(element) {    return element._zid || (element._zid = _zid++) };function add(...){var id = zid(element), set = (handlers[id] || (handlers[id] = []));...};
$(".out").on('click',function(event) {  console.log($(this))  event.stopPropagation();});$(".in").on('click',function(event) {  console.log($(this))});

接下来,add函数定义了一个handler变量。该变量通过将event作为参数传入parse函数获得。

function parse(event) {    var parts = ('' + event).split('.')    //返回一个对象,e为事件的type属性,ns为事件的命名空间    return {e: parts[0], ns: parts.slice(1).sort().join(' ')}  }

接下来,将事件的一系列相关参数放入handler里面,最后设置handler.i为set的长度(作为handler事件的一个index),并将handler放进set,也就是放进handlers[id]。

也就是说,像上面的例子定义之后,handlers里面是这样的(每一个属性代表一个元素里面的事件队列,如1是对应的数组是div.in的事件队列)。

分析handlers相关之后,就可以看remove函数了:

function remove(element, events, fn, selector, capture){   //获得元素在handlers中的对应id    var id = zid(element)    //遍历定义的事件    ;(events || '').split(/\s/).forEach(function(event){      findHandlers(element, event, fn, selector).forEach(function(handler){        delete handlers[id][handler.i]      if ('removeEventListener' in element)        element.removeEventListener(realEvent(handler.e), handler.proxy, eventCapture(handler, capture))      })    })  }

function findHandlers(element, event, fn, selector) {

    event = parse(event)
    if (event.ns) var matcher = matcherFor(event.ns)
    return (handlers[zid(element)] || []).filter(function(handler) {
      return handler
      && (!event.e || handler.e == event.e)
      && (!event.ns || matcher.test(handler.ns))
      && (!fn || zid(handler.fn) === zid(fn))
      && (!selector || handler.sel == selector)
    })
}

 

首先通过finHandlers函数来查询符合的事件,该函数相对简单,通过filter来返回一个符合条件的事件数组,接下来通过delete语句删除handlers[id]中对应的handler,并使用原生的解绑事件解绑。

那么整个事件队列的分析就结束了,之前在分析$.on函数时,也有一个remove没有分析。

$.fn.on = function(event, selector, data, callback, one){    ...    return $this.each(function(_, element){      if (one) autoRemove = function(e){        remove(element, e.type, callback)        return callback.apply(this, arguments)      }      ...      add(element, event, callback, data, selector, delegator || autoRemove)    })  }

 

如果传入了one参数,那么就定义一个autoRemove函数,内部调用remove解绑,并返回绑定事件的执行。这样就保证了只执行一次。

 

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

你可能感兴趣的文章
三分钟,轻松了解Dapp
查看>>
GMQ交易平台满足不同客户群体的多种投资需求
查看>>
大数据开发如何入门你必须知道这些
查看>>
关于js(es5)如何优雅地创建对象
查看>>
阿里云前端周刊 - 第 28 期
查看>>
iOS 主队列同步造成死锁的原因
查看>>
es6 下比较对象是否有修改的简要方法
查看>>
windows安装mysql
查看>>
你还在看《深入理解Java虚拟机》的运行时数据模型吗?
查看>>
RIS,创建 React 应用的新选择
查看>>
线性结构上的动态规划--算法竞赛入门经典笔记
查看>>
面试官:你使用webpack时手写过loader,分离过模块吗?
查看>>
Ubuntu 16.04系统下 对OpenJDK编译好的Hotspot 进行调试
查看>>
00-利用思维导图梳理JavaSE基础知识-持续更新中!
查看>>
java中三种注释及其实际应用的意义
查看>>
【三石jQuery视频教程】01.图片循环展示
查看>>
ngrok
查看>>
ThinkPHP 模板变量输出
查看>>
android系统信息(内存、cpu、sd卡、电量、版本)获取
查看>>
HTML5、WebKit与移动应用开发
查看>>