javascript原生事件总结

javascript原生的事件,总结了一下,包括事件流、处理函数、事件对象这几样东西。而在兼容性方面,主要是老牌ie8以及以下和现代浏览器的差异,也就是ie和DOM事件标准的差异。

  1. 事件流

    这个事件流ie4和Netscape4提出来的,但是两个公司提出的事件流确实刚好相反的。ie的是事件冒泡,Netscape的是事件捕获。

    ie会从触发事件的元素一直往上冒泡直到document元素。如图ie8以下包括ie8的

    javascript原生事件总结_第1张图片

    Netscape则是从document元素开始往下传播一直到触发事件的元素。如图

    javascript原生事件总结_第2张图片

    而DOM标准则建议,将事件流分成三个过程:

    首先捕获阶段:像Netscape那样往下捕获,但是捕获阶段目标元素不会接收到事件。

    然后是目标阶段:就是触发目标元素的事件。

    最后是冒泡阶段:就是想ie那样子的冒泡。

    如图:

    javascript原生事件总结_第3张图片

    但是ie9+,以及别的浏览器所实现的DOM事件流却和标准有点不同。主要是事件流的最顶端延长到window。并且,在捕获阶段目标元素也会接受到一次事件。如图:

    javascript原生事件总结_第4张图片

    也就是说,目标元素的事件会两次触发。

  2. 事件处理程序

    有三种方式给元素绑定事件处理函数。

    a、HTML属性

    <a onclick="alert('click')"></a>

    这样使用在函数里面直接可以调用event,this指向当前元素。但是这种方式一般不适用。

    b、js中元素属性

    这种方式的兼容性好,所有浏览器都支持。但是有一个兼容性问题。那就是ie8-的事件对象是作为window的属性而不是作为参数传进去的。所以要像下面这样写。

    <!doctype html><html lang="en"><head>  <meta charset="UTF-8">  <title>Document</title></head><body>  <a href="##" id="a" style="display:block;width:100px;height:100px;background-color: #ccc;"></a>  <script>    document.getElementById('a').onclick = function(event){      event = event || window.event;      alert(event);    }  </script></body></html>

     

    c、DOM2事件绑定

    主要指的是元素的addEventListener()和removeEventListener()。前者绑定,后者删除。

    这两个函数都有三个参数,

    第一个是事件类型,有click,focus,blur等

    第二个是事件处理函数。

    第三个是个布尔值,true代表在捕获阶段调用处理函数,false代表在冒泡阶段调用处理函数。

    要绑定事件:

    <!doctype html><html lang="en"><head>  <meta charset="UTF-8">  <title>Document</title></head><body>  <a href="##" id="a" style="display:block;width:100px;height:100px;background-color: #ccc;"></a>  <script>    document.getElementById('a').addEventListener('click',function(event){      alert(event);    },false)  </script></body></html>

    假如想解除绑定,有人可能会这样:

    <!doctype html><html lang="en"><head>  <meta charset="UTF-8">  <title>Document</title></head><body>  <a href="##" id="a" style="display:block;width:100px;height:100px;background-color: #ccc;"></a>  <script>    document.getElementById('a').addEventListener('click',function(event){      alert(event);    },false)    document.getElementById('a').removeEventListener('click',function(event){      alert(event);    },false)  </script></body></html>

    但是这样是不会成功的。因为函数是一个对象,两个匿名函数是不同的对象,不相等。所以匿名函数是没办法解绑的。只能想下面这个,个函数一个名号。

    <!doctype html><html lang="en"><head>  <meta charset="UTF-8">  <title>Document</title></head><body>  <a href="##" id="a" style="display:block;width:100px;height:100px;background-color: #ccc;"></a>  <script>    var handler = function(event){      alert(event);    }    document.getElementById('a').addEventListener('click',handler,false)    document.getElementById('a').removeEventListener('click',handler,false)  </script></body></html>

    ie8-的浏览器不支持DOM2级事件,但是有类似的方法 attachEvent()和detachEvent();用法上是一样的,只是因为ie8-只有冒泡过程所以就没有第三个参数。还有第一个参数要加个 ‘on’,比如click事件是‘onclick'。另外,函数内this指向window。

  3. 事件对象

    在js中所有的事件对象都继承自Event。在chrome(左)和firefox(右)中Event对象的样子。 javascript原生事件总结_第5张图片 javascript原生事件总结_第6张图片  

    可以看到在浏览器中Event对象还是有点区别的。但是下面的属性和方法是公用的。

    bubbles 是否冒泡
    cancelable 是否可以取消默认行为
    currentTarget 目前元素
    target 目标元素
    defaultPrevented 是否已被阻止默认行为
    type 事件类型
    eventPhase 事件流哪个阶段1捕获 2目标 3冒泡
    detail 一些信息
    trusted js创建的为false,浏览器创建为true
    view 等同于window
    preventDefault() 阻止默认行为
    stopPropagation() 阻止冒泡和捕获
    stopImmediatePropagation() 立即阻止冒泡和捕获

    在ie8—中事件对象,是这个样子:

    cancelBubble 是否取消冒泡,为true先顶一下stopPropagation()
    returnValue 返回值,为false相当于preventDefault()
    srcElement 目标元素,相当于target
    type 事件类型
  4. UI事件

    load:页面加载完、img图像加载完、所有框架加载完、嵌入内容加载完在object元素触发。在ie9+浏览器中,<script>元素也会触发该事件。

    注意:页面加载完表示,所有的外部css,js,图像等都下载完。

    img元素,一旦加了src属性就开始下载。

    script元素一定要插入文档才开始下载。

    这个事件的事件对象不会包含什么信息,除了在兼容dom的浏览器中有target信息。

    在ie8之前没有加进文档的图像不会生成event对象。

    unload:文档被完全卸载后触发。

    resize:浏览器窗口被调整大小时。

    注意:ie8前event不提供任何属性。

    兼容DOM的浏览器会提供target=document。

    Firefox老版本会在停止改变之后才触发,现在所有浏览器都是每变一个像素都会触发一次。

    scroll:在window对象发生,表示的是文档被滚动。可以通过body元素的scrollLeft和scrollTop来监控。

    注 意:经过测试现在chrome,safari支持body上的这两个属性,ie11,firefox支持documentElement上的这两个属性。 所以要这样写scrollTop = document.documentElement.scrollTop || document.body.scrollTop;

  5. 焦点事件

    focus,focusin 会在得到焦点的元素上触发,focus不冒泡,focusin冒泡。

    blur,focusout在失去焦点的元素上触发,blur不冒泡,focuout冒泡。

     

    1. 鼠标和滚轮事件

      click:可以通过鼠标或键盘触发,冒泡。

      dblclick:通过双击鼠标主按钮触发(有些浏览器中键和右键也可以)。冒泡。

      触发dbclick的过程:mousedown--mouseup--click--mousedown--mouseup--click--dblclick

      但是ie8及以前的浏览器中有bug:mousedown--mouseup--click--mouseup--dblclick

      mousedown/mouseup:按下任意的鼠标键/释放。冒泡。

      注意:当在一个元素按下会触发这个元素的mousedown,如果不释放移动到另一个元素在释放,就会触发后一个元素的mouseup。

      mouseenter:从元素外部进入元素内部触发。不冒泡。进入后代元素不触发。ie、Firefox9+、Opera支持。

      mouseleave:从元素内部移出元素是触发。不冒泡。进入后代元素不触发。ie、Firefox9+、Opera支持。

      mouseover:进入元素内部时触发。冒泡。

      mouseout:移出元素时触发。冒泡。移进后代元素也触发。

      mousemove:在元素内部移动的时候。冒泡。

      在这些事件中,event事件对象会有一些新增的属性。

      在DOM标准中。

      clientX、clientY
      which 1、左 2、右 3、中
      detail 单击次数
      ctrlKey
      altKey
      metaKey
      shiftKey
      pageX、pageY
      screenX、screenY

      在ie8以及以前的浏览器

      clientX、clientY
      button 0:没按下,1:主鼠标,2:次鼠标,3:同时按下主次按钮,4:中间按钮,5:主和中间按钮,6:按下次和右鼠标,7:三个都按下
      offsetX、offsetY
      ctrlKey
      altKey
      metaKey
      shiftKey
      fromElement mouseover
      toElement mouseout

      jquery中对统一用which来代替button和which。

      if ( !event.which && button !== undefined ) {                event.which = ( button & 1 ? 1 : ( button & 2 ? 3 : ( button & 4 ? 2 : 0 ) ) );
                  }

      用位与运算,把button的1、3、5、7修正为1;2,6修正为2;

  6. 键盘与文本事件
     

    keydown:按下键盘任意键触发,按着不放会重复触发。

    keyup:释放键盘按键是触发。

    上面的事件都有一个keyCode,表示按下键的键码。数字字母是ASCII中的数字和 小写字母 的编码。charCode为0.

    在Firefox和Opera中,按下分号keyCode为ASCII的59;ie,Safari和chreome中为键码186.

    keypress:按下字符键是触发。ie9+的浏览器,charCode等于ASCII码。此时的keyCode不确定,不同浏览器可能是0,键码或ASCII码。

    在ie8和Opera中,keyCode等于ASCII码。所以跨浏览器:

         这三个事件的顺序是keydown--keypress--keyup。前两个事件在文本框变化之前。  

    1. charCode = event.charCode || event.keyCode

  7. 变动事件

    DOMSubtreeModified:在DOM结构发生任何变化时候触发,在其他变动事件之后触发。冒泡。目标是插入或者删除的元素的父元素。

    DOMNodeInserted:在一个节点插入另一个节点时触发。冒泡,目标是被插入的节点,event.relatedNode是父元素,触发时已经插入文档。

    DOMNodeInsertedIntoDocument:在DOMNodeInserted之后触发。在DOMNodeInserted之后触发。不冒泡,目标是删除的节点或后代节点,从删除的节点到后代元素的顺序。

    DOMNodeRemoved:在一个节点移除是触发。冒泡。事件目标是被触发的节点,event.relatedNode是父元素,触发时未被从文档中删除。

    DOMNodeRemovedFromDocument:在DOMNodeRemoved之后触发。不冒泡,目标是删除的节点或后代节点,从删除的节点到后代元素的顺序。

    DOMAttrModified:特性被修改之后触发。

    DOMCharacterDataModified:文本节点的值变化的时候触发。

    这些事件要通过DOM2的绑定方法才能绑定成功。ie9+,O9+,FF3+,S3+,C支持。

     


你可能感兴趣的:(javascript原生事件总结)