DOM事件机制相关

参考文章:https://www.cnblogs.com/xiaohuochai/p/5859476.html、https://www.cnblogs.com/xiaohuochai/p/5859674.html                

JavaScript与HTML的交互是通过事件实现的,事件就是文档或浏览器窗口发生的一些特定的交互瞬间,事件流描述的是从页面中接收事件的顺序。事件流到底是怎样的?添加事件监听的方法有哪些?事件对象上有哪些你应该知道的知识点?

一、事件流

1.在DOM兼容浏览器中,事件流分为3个阶段:

    捕获阶段:事件从document节点自上而下向目标节点传播的阶段

    目标阶段:真正的目标节点正在处理事件的阶段。

    冒泡阶段:事件从目标节点自下而上向document传播的阶段。

2.DOM事件流最独特的性质是,文本节点也触发事件,IE除外。

3.addEventListener()方法中的第三个参数,为true是事件捕获阶段,为false是事件冒泡,默认为false。

4.有些事件是可以取消的,在整个事件流的任何位置通过调用事件的stopPropagation方法可以停止事件的传播过程。

二、事件处理程序

事件处理程序又叫事件侦听器,实际上就是事件的绑定函数。事件处理程序有四类,HTML事件处理程序、DOM0级事件处理程序、DOM2级事件处理程序、IE事件处理程序。

1.HTML事件处理程序

    在HTML属性里添加可执行的js代码或者函数,onclick = "test()"。

    HTML事件处理程序会创建一个封装着元素属性值的函数。这个函数中有一个局部变量event,可以直接访问。

    这种事件处理程序的缺点:(1) 时差问题,用户可能会在HTML元素一出现在页面上时就触发相应事件,但当时事件处理程序可能还不可用,就会报错。(2)耦合问题,最好是保持HTML和JS行为分离,但是这种方式会将JS混合在HTML属性中,且不易扩展。

2.DOM0级事件处理程序

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

    box.onclick = function(){} // 添加

    box.onclick =  null  //删除

    以这种方式添加的事件处理程序会在事件的冒泡阶段被处理。

    缺点:每个元素对每种事件类型只能添加一个事件处理程序。

3.DOM2级事件处理程序

    addEventListener()和removeEventListener(),接受3个参数,事件名、函数和布尔值,为true时表示在捕获阶段调用函数,为false表示在冒泡阶段调用函数,默认为false。

    IE8不支持DOM2级事件处理程序

    一个元素可以添加多个同类型的事件处理程序,不会被覆盖,按照添加顺序依次触发。

    通过该addEventListener添加的函数,只能通过removeEventListener移除,且参数必须相同。另外,添加的匿名函数将无法移除。

4.IE事件处理程序

    attachEvent()和detachEvent(),接收两个参数,都会被添加到冒泡阶段

    与其他3个事件处理不同,IE程序里的this指向window,而不是被绑定的元素。

    attachEvent()添加多个事件处理时,IE9、10浏览器正序执行的,而IE8-浏览器倒序执行。

    移除同上一种。

事件处理程序总结:

    全浏览器的事件绑定兼容写法;

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

    同时出现HTML事件处理和DOM0级,DOM0级会覆盖HTML。

三、事件对象

触发DOM上的某个事件时,会产生一个事件对象event,它包含着所有与事件有关的信息,所有浏览器都支持event,只不过方式不同。

1.获取事件对象

    (1)event 是时间程序的第一个参数,不过IE8不支持

    (2)直接在函数中使用event对象,不过firefox不支持

    (3)兼容写法 oBox.onclick = function(e){  e=e||event }

2.属性和方法

    (1)事件类型:click、mouseout、mouseover、focus(button按钮可以通tab键触发focus事件)

    (2)事件目标

    currentTarget:事件正在执行的监听函数所绑定的节点,IE8不支持

    target:事件的实际目标节点,IE8不支持。事件绑定在外层元素,点击内层中的一个元素,此时target是内层元素,currentTarget是外层元素。

    srcElement:通target,firefox不支持

    (3)事件代理

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

    事件代理应用目标的target和srcElement属性完成。

    使用事件代理可以提高性能及降低代码复杂度。

    如果可行的话,可以考虑为document添加一个事件处理函数,用以处理页面上发生的某种特定类型的事件。这样做与传统方法的优点:第一,document对象很快就可以访问,而且可以在页面的生命周期的任何时间点上为它添加事件处理函数,而不需等待DOMContentLoaded或load事件。也就是,只有可单击的元素呈现在页面上,就可以立即具备相应功能。第二,只添加一个事件处理所需的DOM引用更少,所花的时间也更少。第三,整个页面占用的内存空间更少,能够提升整体性能。

    适合使用事件委托的事件有:click、mousedown、mouseup、keydown、keyup、keypress

    (4)事件冒泡

    关于冒泡,事件对象中包含bubbles、cancelBubble、stopPropagation()和stopImmediatePropagation()

    bubbles:只读,布尔值,当前事件是否会冒泡。只有focus、blur、scroll事件不会冒泡,其他都会。

    cancelBubble:可读写,布尔值,用于阻止冒泡,默认false,全浏览器支持。

    stopPropagation():取消事件的进一步捕获或冒泡(根据事件添加在捕获还是冒泡阶段,来确定这里是取消捕获还是冒泡),无返回值,IE8不支持。

    stopImmediatePropagation(): 不仅取消事件的进一步捕获或冒泡,还会阻止同一事件的其他监听函数被调用,无返回值,IE8不支持。

    使用stopPropagation()或stopImmediatePropagation()之后,cancelBubble属性会发生变化,但是不同浏览器表现不同。chrome/safari/opera中,cancelBubble的值仍为false;IE9+/firefox中,cancelBubble的值会变为true。

    通过上面的属性和方法,你会"阻止事件冒泡"的兼容写法吗?    

    (5)事件流

    eventPhase:返回整数值0-3,0表示事情没有发生,1是捕获阶段,2是目标阶段,3是冒泡阶段。IE8不支持。

    (6)取消默认行为

    常见的默认行为有:点击链接后,跳到指定页面;按空格键,页面向下滚动一段距离。

    关于取消默认行为的方法和属性:

    cancelable:只读,布尔值,事件是否可取消,IE8不支持。

    preventDefault():取消浏览器对当前事件的默认行为,无返回值,IE8不支持。

    returnValue:可读写,默认true,设置为false就可以取消事件的默认行为。firefox和IE9+不支持

    return false :在事件处理程序中,直接return false,就可以取消默认事件,DOM2级事件处理使用此方法无效。

    defaultPrevented:默认行为是否被阻止了。IE8不支持。

你可能感兴趣的:(DOM事件机制相关)