事件对象

给元素的事件行为绑定方法,当事件行为触发会被执行,同时还会把当前操作的相关信息传递给这个函数=》
事件对象

  1. 当是鼠标操作,获取的是MouseEvent类的实例=》鼠标事件对象

    MouseEvent.prototype -> UIEvent.prototype -> Event.prototype -> Object.prototype

  2. 当时键盘操作,获取的是KeyboardEvent类的实例=》键盘事件对象

  3. 普通事件对象(event),手指事件对象…

    鼠标事件对象

    clientX|clientY

    当前鼠标触发点距离当前窗口左上角的X|Y轴坐标

    pageX|pageY

client与page的区别

触发点距离当前页面左上角的X|Y轴坐标

type:触发事件的类型

target:

事件源(操作的是哪个元素,哪个元素就是事件源),在不兼容的浏览器中可以使用srcElement获取,也代表的是事件源

冒泡和默认行为

阻止默认行为

preventDefault():用来阻止默认行为的方法,不兼容的浏览器中用ev.returnValue=false也可以阻止默认行为

阻止冒泡行为

stopPropagation():阻止冒泡传播,不兼容的浏览器中用ev.cancelBubble=true也可以阻止默认行为

  1. 事件对象和函数以及给谁绑定的事件没啥必然关系,它存储的是当前本次操作的相关信息,操作一次只能有一份信息,所以在哪个方法中获取的信息都是一样的;
  2. 第二次操作,存储的信息会把上一次操作存储的信息替换掉...;

事件触发,浏览器处理过程

  1. 捕获到当前操作的行为(把操作信息获取到),通过创建MouseEvent等类的实例,得到事件对象EV
  2. 通知所有绑定的方法(符合执行条件的)开始执行,并且把EV当做实参传递给每个方法,所以在每个方法中得到的事件对象其实是一个
  3. 后面再重新触发这个事件行为,会重新获取本次操作的信息,用新的信息替换老的信息,然后继续之前的步骤
  1. let obj=null;
  2. box.addEventListener('click',function(ev){
  3. console.log(ev);
  4. obj=ev;
  5. });
  6. box.addEventListener('click',function(ev){
  7. console.log(ev===obj);//true
  8. });
  9. document.body.onclick=function(ev){
  10. console.log(ev===obj);//true
  11. }

事件传播机制

捕获阶段:从最外层向最里层事件源依次进行查找(目的:是为冒泡阶段事先计算好传播的层级路径)
=>CAPTURING_PHASE:1
目标阶段:当前元素的相关事件行为触发 =>AT_TARGET:2
冒泡传播:触发当前元素的某一个事件行为,不仅它的这个行为被触发了,而且它所有的祖先元素(一直到window)相关的事件行为都会被依次触发(从内到外的顺序) =>BUBBLING_PHASE:3 (Event.prototype)

image.png

  1. * xxx.onxxx=function(){} DOM0事件绑定,给元素的事件行为绑定方法,这些方法都是在当前元素事件行为的
  2. 冒泡阶段(或者目标阶段)执行的
  3. * xxx.addEventListener('xxx',function(){},false) 第三个参数FALSE也是控制绑定的方法在事件传播
  4. 的冒泡阶段(或者目标阶段)执行;只有第三个参数为TRUE才代表让当前方法在事件传播的捕获阶段触发执行(这种
  5. 捕获阶段执行没啥实际意义,项目中不用);
  6. * 不同浏览器对于最外层的祖先元素的定义不同
  7. 谷歌:window->document->html->body...
  8. IE高:window->html->body...
  9. IE低:html->body...

对于事件对象的理解

  • 事件对象是用来存储当前本次操作的相关信息,和操作有关,和元素无必然关联
  • 当我们基于鼠标或者键盘等操作的时候,浏览器会把本次操作的信息存储起来(标准浏览器存储到默认的内存中(自己找不到),IE低版本存储到window.event中了),存储的值是一个对象(堆内存);操作肯定会触发元素的某个行为,也就会把绑定的方法执行,此时标准浏览器会把之前存储的对象(准确来说是堆内存地址)当做实参传递给每一个执行的方法,所以操作一次,即使再多方法中都有EV,但是存储的值都是一个(本次操作信息的对象而已)

    mouseenter和mouseover

    ```javascript
  1. over属于滑过(覆盖)事件,从父元素进入到子元素,属于离开了父元素,会触发父元素的out,触发子元素的over enter属于进入,从父元素进入子元素,并不算离开父元素,不会触发父元素的leave,触发子元素的enter
  2. enter和leave阻止了事件的冒泡传播,而over和out还存在冒泡传播的,所以对于父元素嵌套子元素这种情况, 使用over会发生很多不愿意操作的事情,此时我们使用enter会更加简单,操作方便,所以真实项目中enter的使 用会比over多 ```

image.png