JavaScript事件

2020-12-13 01:39

阅读:340

YPE html>

元素

技术图片

注意:IE9、Firefox、Chrome、safari等现代浏览器都支持事件捕获,但从window对象开始获取

技术图片

addEventListener(eventType,eventListener,useCapture)方法中的第三个参数设置为true时,即为事件捕获阶段

事件流

? 事件流又称为事件传播,DOM2级事件规定的事件流包括三个阶段:事件捕获阶段(capture phase)、处于目标阶段(target phase)和事件冒泡阶段(bubbling phase)

  首先发生的是事件捕获,为截获事件提供了机会。然后是实际的目标接收到事件,最后一个阶段是冒泡阶段,可以在这个阶段对事件做出响应

技术图片

事件处理程序

事件处理程序又叫事件侦听器,实际上就是事件的绑定函数。事件发生时会执行函数中相应代码。事件处理程序:

  1. HTML事件处理程序
  2. DOM0级事件处理程序
  3. DOM2级事件处理程序
  4. IE事件处理程序

下面将详细介绍该部分内容

HTML事件处理程序

? 某个元素支持的每种事件,都可以使用一个与相应事件处理程序同名的HTML特性来指定。这个特性的值应该是能够执行的javascript代码

? 在事件处理程序函数内部,this等于事件的目标元素

? 在HTML中定义的事件处理程序也可以调用在页面其它地方定义的脚本

HTML事件处理程序会创建一个封装着元素属性值的函数。这个函数中有一个局部变量event,也就是事件对象。通过event变量,可以直接访问事件对象,不用自己定义它,也不用从函数的参数列表中获取。(下节会重点讲事件对象上的属性)

 在事件处理程序函数内部,可以像访问局部变量一样访问document及该元素本身的成员。如此一来,事件处理程序要访问自己的属性就简单多了

缺点

耦合问题

? 客户端编程的通用风格是保持HTML内容和javaScript行为分离,所以应该避免使用HTML事件处理程序属性,因为这些属性直接混合了javascript和HTML,且不易扩展

DOM0级事件处理程序

? 通过javascript指定事件处理程序的传统方式,就是将一个函数赋值给一个事件处理程序属性。这种为事件处理程序赋值的方法是在第四代Web浏览器中出现的,而且至今仍然为所有现代浏览器所支持。原因一是简单,二是具有跨浏览器的优势

  每个元素都有自己的事件处理程序属性,这些属性通常全部小写,将这种属性的值设置为一个函数,就可以指定事件处理程序

注意:以DOM0级方式添加的事件处理程序会在事件流的冒泡阶段被处理

? 可以通过将事件处理程序属性设置为null来删除事件处理程序

box.onclick = null;
缺点

? 围绕着每个事件目标对于每种事件类型只能添加一个事件处理程序

DOM2级事件处理程序

? DOM2级事件处理程序定义了两个方法用于处理指定和删除事件处理程序的操作:addEventListener()removeEventListener()

? 所有DOM节点中都包含这两个方法,并且它们都接受3个参数:要处理的事件名作为事件处理程序的函数一个布尔值。最后的布尔值参数如果是true,表示在捕获阶段调用事件处理程序;如果是false,表示在冒泡阶段调用事件处理程序。若最后的布尔值不填写,则和false效果一样

注意: IE8浏览器不支持DOM2级事件处理程序

? 使用DOM2级事件处理程序的好处是可以添加多个事件处理程序,并按照他们添加的顺序触发

得到输出结果为: 12

可以做个延迟操作来验证:

得到输出的结果为:21

参数

? 如果希望向监听函数传递参数,可以用匿名函数包装一个监听函数

移除

? 通过addEventListener()添加的事件处理程序只能使用removeEventListener()来移除,移除时传入的参数与添加处理程序时使用的参数相同。这意味着,addEventListener()添加的匿名函数将无法移除。 

以下无效

以下有效

IE事件处理程序

? IE实现了与DOM中类似的两个方法:attachEvent()和detachEvent()。这两个方法接受相同的两个参数:事件处理程序名称与事件处理程序函数。由于IE8-浏览器只支持事件冒泡,所以通过attachEvent()添加的事件处理程序都会被添加到事件冒泡阶段

? attachEvent()方法的第一个参数是"onclick",而非DOM的addEventListener()方法中的"click"

注意:attachEvent()方法只冒泡到document,且IE10-浏览器支持

this

? 与其他三个事件处理程序不同,IE事件处理程序的this指向了window,而非被绑定事件的元素。


顺序

?  使用attachEvent()方法添加的事件处理程序的触发顺序是有区别的。IE9、10浏览器是按正序执行的,而IE8-浏览器则是按倒序执行的  

移除

? 使用attachEvent()添加的事件可以通过detachEvent()来移除,条件是必须提供相同的参数。与DOM方法一样,这也意味着添加的匿名函数将不能被移除。不过,只要能够将对相同函数的引用传给detachEvent(),就可以移除相应的事件处理程序 

以下无效

以下有效

总结

? 由于IE8-浏览器不支持addEventListener()方法,所以需要配合attachEvent()方法来实现全浏览器的事件绑定兼容写法。同时,由于attachEvent()方法中的this指向window,所以需要对this进行显式修改。

function addEvent(target,type,handler){
    if(target.addEventListener){
        target.addEventListener(type,handler,false);
    }else{
        target.attachEvent('on'+type,function(event){
            return handler.call(target,event);
        });
    }
}

调用顺序

? 如果浏览器同时出现这四种事件处理程序,那么它们的调用顺序在各浏览器中表现并不一致 

【相同点】

  如果同时出现HTML事件处理程序和DOM0级事件处理程序,DOM0级会覆盖HTML事件处理程序

【不同点】

  chrome/safari/FF以及IE11浏览器结果为:DOM0级 DOM2级

  IE9、10浏览器结果为:DOM0级 DOM2级 IE

  IE8-浏览器结果为:DOM0级 IE

事件对象

  在触发DOM上的某个事件时,会产生一个事件对象event,这个对象中包含着所有与事件有关的信息。所有浏览器都支持event对象,但支持方式不同。本文将详细介绍事件对象

获取事件对象

1) event对象是事件程序的第一个参数

注意: IE8 浏览器不支持


2) 另外一种方法是直接使用event变量

Firefox浏览器不支持


兼容

? 于是,获取事件对象的常见兼容性写法如下

? 通过点击按tab键将焦点切换到button按钮上可以出发focus事件


事件目标

? 关于事件目标,共有currentTarget、target、srcElement这三个属性

currentTarget

? currentTarget属性返回事件当前所在的节点,即正在执行的监听函数所绑定的那个节点

IE8 浏览器不支持

currentTarget属性返回事件当前所在的节点,即正在执行的监听函数所绑定的那个节点


  • 1
  • 2
target

? currentTarget属性返回事件正在执行的监听函数所绑定的节点,而target属性返回事件的实际目标节点

IE8 浏览器不支持

以下代码中,点击该实际目标节点时,颜色变红;移出,颜色变浅蓝


  • 1
  • 2
srcElement

? srcElement属性与target属性功能一致

注意:Firefox浏览器不支持


  • 1
  • 2
兼容
var handler = function(e){
    e = e || event;
    var target = e.target || e.srcElement;
}

事件代理

 由于事件会在冒泡阶段向上传播到父节点,因此可以把子节点的监听函数定义在父节点上,由父节点的监听函数统一处理多个子元素的事件。这种方法叫做事件的代理(delegation),也叫事件委托

  事件代理应用事件目标的target和srcElement属性完成。利用事件代理,可以提高性能及降低代码复杂度。

? 举个列子:有三个同事预计会在周一收到快递。为签收快递,有两种办法:一是三个人在公司门口等快递;二是委托给前台MM代为签收。现实当中,我们大都采用委托的方案(公司也不会容忍那么多员工站在门口就为了等快递)。前台MM收到快递后,她会判断收件人是谁,然后按照收件人的要求签收,甚至代为付款。这种方案还有一个优势,那就是即使公司里来了新员工(不管多少),前台MM也会在收到寄给新员工的快递后核实并代为签收。

需求:一个ul中有5个li,移入时变蓝,移出时变红

下面分别用常规方法和事件代理方法来实现





  • 1
  • 2
  • 3
  • 4
  • 5

需求:给未来添加的元素添加事件



    



  • 1
  • 2
  • 3
  • 4
  • 5

事件冒泡

? 事件冒泡是事件流的第三个阶段,通过事件冒泡可以在这个阶段对事件做出响应

? 关于冒泡,事件对象中包含bubblescancelBubblestopPropagation()stopImmediatePropagation()这四个相关的属性和方法。

bubbles

? bubbles属性返回一个布尔值,表示当前事件是否会冒泡。该属性为只读属性

? 发生在文档元素上的大部分事件都会冒泡,但focus、blur和scroll事件不会冒泡。所以,除了这三个事件bubbles属性返回了false外,其它事件该属性都为true


内容
stopPropagation()

? stopPropagation()方法表示取消事件的进一步捕获或冒泡,无返回

注意:ie8 浏览器不支持



    



        
stopImmediatePropagation()

? stopImmediatePropagation()方法不仅可以取消事件的进一步捕获或冒泡,而且可以阻止同一个事件的其他监听函数被调用,无返回值

 [注意]IE8-浏览器不支持

? 使用stopIPropagation()方法,可以阻止冒泡,但无法阻止同一事件的其他监听函数被调用



    



        

使用stopImmediatePropagation()方法,即可以阻止冒泡,也可以阻止同一事件的其他监听函数被调用


cancelBubble

? canceBubble属性只能用于阻止冒泡,无法阻止捕获阶段。该值可读写,默认值为false。当设置为true是,cancelBubble可以取消事件冒泡

[注意]该属性全浏览器支持,但并不是标准写法


兼容
var handler = function(e){
    e = e || event;
    if(e.stopPropagation){
        e.stopPropagation();
    }else{
        e.cancelBubble = true;
    }
}

事件流阶段

eventPhase

? eventPhase属性返回一个整数值,表示事件目前所处的事件流阶段

  0表示事件没有发生,1表示捕获阶段,2表示目标阶段,3表示冒泡阶段

  [注意]IE8-浏览器不支持

【1】以下代码返回2,表示处于目标阶段


【2】以下代码返回1,表示处于捕获阶段


【3】以下代码返回3,表示处于冒泡阶段


取消默认行为

? 常见的默认行为有点击链接后,浏览器跳转到指定页面;或者按一下空格键,页面向下滚动一段距离

? 关于取消默认行为的属性包括preventDefault()returnValue

使用

  1、在DOM0级事件处理程序中取消默认行为,使用returnValue、preventDefault()和return false都有效

  2、在DOM2级事件处理程序中取消默认行为,使用return false无效

  3、在IE事件处理程序中取消默认行为,使用preventDefault()无效

点击下列锚点时,会自动打开小猿圈首页

小猿圈
preventDefault()

? preventDefault()方法取消浏览器对当前事件的默认行为,无返回值

注意:IE8浏览器不支持

链接
returnValue

? returnValue属性可读写,默认值是true,但将其设&am


评论


亲,登录后才可以留言!