[事件监听]---------个人对于事件监听的理解 (包含冒泡与捕获)
[事件监听]———个人对于事件监听的理解 (包含冒泡与捕获)
最近常听到别人问我= = 事件监听是什么? 你是怎样理解事件监听的? 故此想到写一篇博 来谈谈我对于事件监听的理解.
首先,说起时间监听 不得不提的就是DOM0级事件与DOM2级事件了
1.DOM0级事件:
DOM0级事件 有俩个表现形式 : 一是在标签内写onclick事件 还一个是在JS写 onlicke=function(){} 函数, 这里主要讲一下在JS中的这种表现形式 痛过上一句话 我们不难看出是怎样一个形式 首先得有事件源 然后是事件类型 再后面是预处理函数 普通的这样类型的就是DOM0级事件了
0级事件取消事件的方法 : 事件源.事件类型 = null ;
在这里我们要说一下DOM0级事件的一个缺点 那就是 后者的事件会覆盖前者的事件 听到这句话想必大家就会觉得说 “这样岂不是会很乱啊 挺烦的” 对!没错 确实挺烦 不过安啦 接下来要讲到的DOM2级事件 就能够解决这个事情了
2.DOM2级事件:
上面说到了DOM2级事件可以解决那个覆盖的问题 想必大家也很好气吧 哈哈 现在就来告诉你把 DOM2级事件也叫做事件监听(为同一个对象的同一个事件绑定多个事件处理程序) 什么?很熟悉?这是当然的啦 这就是我们今天的主题啊 你不知道?你怕不是都没看标题就进来了吧…
不扯了…进入正题: 其实说白了 这就是一个监听方法 用来处理函数的 可以添加与删除 分别用 addEventListener 和 removeEventListener
addEventListener 其中有3个参数 (前者事件先执行,后者事件后执行)
参数一 : 事件类型 (这个事件类型可以不加on)
参数二 : 回调函数
参数三 : 布尔值 (true跟false) true代表事件捕获 false代表事件冒泡 默认是false (这边提到的事件冒泡还有事件捕获我会在下面说明 )
removeEventListener 只有一个参数 : 需要解绑的那个事件.
然而在IE里面上面的方法是不行的 所以我们这边用 attachEvent 和detachEvent 来在IE里面实现
attachEvent 其中有2个参数 (后者事件先执行,前者事件后执行)
参数一 : 事件类型 (这个事件类型必须加on)
参数二 : 回调函数
detachEvent 只有一个参数 : 需要解绑的那个事件
想必大家也看到上面所提到的冒泡跟捕获了吧 为了让你更加理解上面 这边我就来说一下冒泡跟捕获
在讲之前 首先我们得知道一个东西 那就是事件流! 那么什么是事件流呢? 当一个元素触发一个事件的时候 这个事件会在元素节点与根节点的传播路径上传播,
当子级触发事件的时候会形成一个事件流的事件将子级的事件冒泡到父级上去
事件捕获 : 由网景提出的
当父级触发事件的时候 会形成一个事件流 将父级的事件传播到子级上去
上面说的那么官方 你可能不是很理解 这样说吧 你就可以把事件冒泡想象成 古时候为民请命 联名上表一样 百姓们就相当于子级事件 当百姓们有了冤屈时并不能直接跟皇上面前告御状是吧 又不是现在很多公司都有的政策 扫码向老板提意见 古时候都要经过层层传递 先上报地方官员 地方再上报到京城中能上去金銮殿的大官 最终才能到达皇帝那 冒泡也是这样 由子级一层一层向上到达父级 然后同样的捕获就相当于 皇帝下达圣旨 但是接收圣旨的人在一个偏远的地方的某个人 那么会怎样呢?还不是一级一级的下来 传到那人那里 简单来说就是个传递问题 要区分冒泡捕获 重要的是搞清楚谁传谁
关于冒泡和捕获 还有一点值得注意的就是 当事件冒泡跟事件捕获同时执行的时候 先执行捕获 后执行冒泡 (当执行时 捕获的倒数第一个事件 跟冒泡的第一个事件换位时 那么就是按照顺序执行了)
在这里还得提一下事件冒泡的坏处
坏处 : 在给子级添加事件后.点击子级后会冒泡到父级,若此时父级设置了”none”之类的属性时,子级里的内容会被”none”掉,无法呈现 带来了不便
这个时候 我们可以通过阻止事件冒泡来解决此类问题 阻止事件冒泡 : e.stopPropagation IE不支持这个方法 所以我们用 e.cancelBubble = true 来达到效果; 我们可以用三目做一个兼容 : e.stopPropagation ? e.stopPropagation() : e.cancelBubble = true ;
好处 : 我们可以通过事件冒泡的原理 来进行事件绑定或者说事件委托 利用事件冒泡的原理 将子级的事件委托给父级 这样就大大减少了事件的绑定 提高了性能 通过这个方法我们还可以实现对未来元素的事件绑定 可以说是很方便了
因为上面的事件委托 我们将事件绑定在了父级上 而为了找到具体是谁触发了某个事件 我们需要找到事件源
获取事件源 : var target = e.target||e.srcElement (tagName能找到事件源的元素名)