元素天生自带的事件

鼠标事件

  • click:点击 (PC端是点击,移动端的click代表单击[移动端使用click会有300MS延迟的问题])

  • dblclick:双击

  • mouseover:鼠标经过

  • mouseout:鼠标移出

  • mouseenter:鼠标进入

  • mouseleave:鼠标离开

  • mousemove:鼠标移动

  • mousedown:鼠标按下(鼠标左右键都起作用,它是按下即触发,click是按下抬起才会触发,而且是先把down和up触发,才会触发click)

  • mouseup:鼠标抬起

  • mousewheel:鼠标滚轮滚动


键盘事件

  • keydown:键盘按下

  • keyup:键盘抬起

  • keypress:和keydown类似,只不过keydown返回的是键盘码,keypress返回的是ASCII码值

  • input:由于PC端有实体物理键盘,可以监听到键盘的按下和抬起,但是移动端是虚拟的键盘,所以keydown和keyup在大部分手机上都没有,我们使用input事件统一代替他们(内容改变事件)

  • ...


表单元素常用的事件

  • focus:获取焦点

  • blur:失去焦点

  • change:内容改变

  • ...


其它常用事件

  • load:加载完成

  • unload

  • beforeunload

  • scroll:滚动条滚动事件

  • resize:大小改变事件 window.onresize=function(){} 当浏览器窗口大小发生改变,会触发这个事件,执行对应的事情

  • ...


移动端手指事件

  • [touch:单手指操作]

    1. touchstart:手指按下

    2. touchmove:手指移动

    3. touchend:手指离开

    4. touchcancel:因为意外情况导致手指操作取消 *

  • [gesture:多手指操作]

    1. gesturestart:手指按下

    2. gesturechange:手指改变

    3. gestureend:手指离开

    4. ...

  • [H5中的AUDIO/VIDEO音视频事件]

    1. canplay:可以播放(播放过程中可能出现由于资源没有加载完成,导致的卡顿)

    2. canplaythrough:资源加载完成,可以正常无障碍播放

    3. ...

事件绑定

DOM0级事件绑定

[element].onxxx=function(){}

//=>DOM0事件绑定:只允许给当前元素的某个事件行为绑定一个方法,多次绑定,后面绑定的内容会替换前面绑定的,以最后一次绑定的方法为主
   box.onclick = function () {
       console.log(1);
  };
   box.onclick = function () {
       console.log(2);//=>触发点击行为,只输出2
  };

DOM2级事件绑定

添加:[element].addEventListener('xxx',function(){},false)

移除:[element].removeEventListener('xxx',function()

[IE6~8]:[element].attachEvent('onxxx',function(){}) 移除使用的是dettachEvent。

DOM2事件绑定可以给当前元素的某一个事件行为绑定“多个不同的方法”。


DOM0事件绑定和DOM2事件绑定的区别

  • DOM0采用的是给私有属性赋值,所以只能绑定一个方法

  • DOM2采用的是事件池机制,所以能绑定多个不同的方法

  • DOM2事件绑定中增加了一些DOM0无法操作的事件行为,例如:DOMContentLoaded事件(当页面中的HTML结构加载完成就会触发执行)

事件对象

当事件函数触发执行时,浏览器还给函数传递了一个实参信息值 ==>这个值就是事件对象(MouseEvent鼠标事件对象、KeyboardEvent键盘事件对象、Event普通事件对象...)

MouseEvent

  • ev.target:事件源(操作的是哪个元素)

  • ev.clientX / ev.clientY :当前鼠标触发点距离当前窗口左上角的X/Y轴坐标

  • ev.pageX / ev.pageY:当前鼠标触发点距离BODY(第一

    屏幕)左上角的X/Y轴坐标

  • ev.preventDefault():阻止默认行为

  • ev.stopPropagation():阻止事件的冒泡传播

  • ev.type:当前事件类型

KeyboardEvent

  • ev.code:当前按键'keyE'

  • ev.key:当前按键'e'

  • ev.which / ev.keyCode:当前按键的键盘码 69

    /*

    • 左-上-右-下:37-38-39-40

    • Backspace:8

    • Enter:13

    • Space:32

    • Delete:46 *

    • Shift:16

    • Alt:18

    • Ctrl:17

    • ESC:27 *

    • F1~F12:112 ~ 123

    • 48~57:数字键

    • 65~90:小写字母 */

IE6~8

box.onclick = function (ev) {
    //=>在IE低版本浏览器中,浏览器执行绑定的方法,并没有把事件对象传递进来,此时ev===undefined,需要基于window.event来获取(由于是全局属性,鼠标每次操作都会把上一次操作的值替换掉)
    if (!ev) {
        //=>低版本中没有的属性,我们手动设置一下:按照自己有的先获取到值,然后赋值给和标准对应的新属性(经过判断处理后,低版本中也有TARGET/PAGE-X/PAGE-Y这些属性了),后期再使用的时候,直接按照高版本的使用即可
        ev = window.event;
        // console.log(ev.srcElement);//=>ev.srcElement是获取事件源(标准中使用的是ev.target)
        ev.target = ev.srcElement;
        // console.log(ev.pageX);//=>低版本浏览器的事件对象中不存在pageX/pageY
        ev.pageX = ev.clientX + (document.documentElement.scrollLeft || document.body.scrollLeft);
        ev.pageY = ev.clientY + (document.documentElement.scrollTop || document.body.scrollTop);
        ev.which = ev.keyCode;
​
        // preventDefault & stopPropagation 这些在低版本下都没有
        ev.preventDefault = function () {
            ev.returnValue = false;//=>低版本阻止默认行为
        };
        ev.stopPropagation = function () {
            ev.cancelBubble = true;//=>低版本阻止冒泡传播
        };
    }
    //=>直接按照高版本的规则来使用即可
    console.log(ev.target, ev.which);
    ev.preventDefault();
    ev.stopPropagation();
};

 

 

事件的传播机制

  • 第一阶段:从window对象传导到目标节点,称为“捕获阶段”(capture phase)。

  • 第二阶段:在目标节点上触发,称为“目标阶段”(target phase)。

  • 第三阶段:从目标节点传导回window对象,称为“冒泡阶段”(bubbling phase)。 这种三阶段的传播模型,会使得一个事件在多个节点上触发。

不同浏览器对于最外层祖先元素的定义是不一样的

谷歌:window->document->html->body...

IE高:window->html->body...

IE低:html->body...

事件委托

利用事件的冒泡传播机制,如果一个容器的后代元素中,很多元素的点击行为(其它事件行为也是)都要做一些处理,此时我们不需要在像以前一样一个个获取一个个的绑定了,我们只需要给容器的CLICK绑定方法即可,这样不管点击的是哪一个后代元素,都会根据冒泡传播的传递机制,把容器的CLICK行为触发,把对应的方法执行,根据事件源,我们可以知道点击的是谁,从而做不同的事情即可,事件委托这种处理方式比一个个的事件绑定,性能提高50%左右,需要的元素越多,性能提高越大