JS语法:DOM事件过程 事件设计 事件委托

前端之家收集整理的这篇文章主要介绍了JS语法:DOM事件过程 事件设计 事件委托前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

事件绑定

  • 方式4:IE下使用attachEvent/detachEvent函数进行事件绑定和取消。

attachEvent/detachEvent兼容性不好,IE6~IE11都支持该函数,但是FF和Chrome浏览器都不支持该方法。而且attachEvent/detachEvent不是W3C标准的做法,所以不推荐使用。在IE浏览器下,attachEvent有以下特点。

a) 事件处理函数中this代表的是window对象,不是dom对象。

var dom = document.getElementById("outestA");  
dom.attachEvent('onclick',a);  

function a()
{
alert(this.id);//undefined
}

b) 同一个事件处理函数只能绑定一次。

var dom = document.getElementById("outestA");  
dom.attachEvent('onclick',a);  
dom.attachEvent('onclick',a);    
function a()  
{  
    alert(this.id);
}

虽然使用attachEvent绑定了2次,但是函数a只会调用一次。

c)不同的函数对象,可以重复绑定,不会覆盖。

var dom = document.getElementById("outestA");  
dom.attachEvent('onclick',function(){alert(1);});  
dom.attachEvent('onclick',function(){alert(1);});  

// 当outestA的click事件发生时,会弹出2个对话框

匿名函数和匿名函数是互相不相同的,即使代码完全一样。所以如果我们想用detachEvent取消attachEvent绑定的事件处理函数,那么绑定事件的时候不能使用匿名函数,必须要将事件处事函数单独写成一个函数,否则无法取消。

  • 方式5:使用W3C标准的addEventListener和removeEventListener。

这2个函数是W3C标准规定的,FF和Chrome浏览器都支持,IE6/IE7/IE8都不支持这2个函数。不过从IE9开始就支持了这2个标准的API。
JavaScript

// type:事件类型,不含"on",比如"click"、"mouseover"、"keydown";
// 而attachEvent的事件名称,含含"on",比如"onclick"、"onmouseover"、"onkeydown";
// listener:事件处理函数
// useCapture是事件冒泡,还是事件捕获,默认false,代表事件冒泡类型
addEventListener(type,listener,useCapture);

a) 事件处理函数中this代表的是dom对象,不是window,这个特性与attachEvent不同。

var dom = document.getElementById("outestA");  
dom.addEventListener('click',a,false);  

function a()
{
alert(this.id);//outestA
}

b) 同一个事件处理函数可以绑定2次,一次用于事件捕获,一次用于事件冒泡。

var dom = document.getElementById("outestA");  
dom.addEventListener('click',false);  
dom.addEventListener('click',true);  

function a()
{
alert(this.id);//outestA
}

// 当点击outestA的时候,函数a会调用2次
如果绑定的是同一个事件处理函数,并且都是事件冒泡类型或者事件捕获类型,那么只能绑定一次。

var dom = document.getElementById("outestA");  
dom.addEventListener('click',false);  

function a()
{
alert(this.id);//outestA
}

// 当点击outestA的时候,函数a只会调用1次
c) 不同的事件处理函数可以重复绑定,这个特性与attachEvent一致。

事件执行顺序

addEventListener和attachEvent表现一致,如果给同一个事件绑定多个处理函数,先绑定的先执行。



    
//当点击outA的时候,会依次打印出1、2、3、4。

给outA绑定了多个onclick事件处理函数,也是直接点击outA触发的事件,所以不涉及事件冒泡和事件捕获的问题,即addEventListener的第三个参数在这种场景下,没有什么用处。如果是通过事件冒泡或者是事件捕获触发outA的click事件,那么函数的执行顺序会有变化。

事件冒泡和事件捕获

DOM事件流

DOM事件流:将事件分为三个阶段:捕获阶段、目标阶段、冒泡阶段。先调用捕获阶段的处理函数,其次调用目标阶段的处理函数,最后调用冒泡阶段的处理函数



    

当点击outC的时候,依次打印出capture1–>capture2–>target–>bubble2–>bubble1。

useCapture=false意味着:将事件处理函数加入到冒泡阶段,在冒泡阶段会被调用;useCapture=true意味着:将事件处理函数加入到捕获阶段,在捕获阶段会被调用。从DOM事件流模型可以看出,捕获阶段的事件处理函数,一定比冒泡阶段的事件处理函数先执行。

目标阶段执行先后顺序



    

点击outC的时候,打印顺序是:capture1–>capture2–>target2–>target1–>bubble2–>bubble1

目标阶段函数的执行顺序:先注册的先执行,后注册后执行。这就是上面我们说的,在目标对象上绑定的函数是采用捕获,还是采用冒泡,都没有什么关系,因为冒泡和捕获只是对父元素上的函数执行顺序有影响,对自己没有什么影响。

// 目标(自身触发事件,是冒泡还是捕获无所谓)
outC.addEventListener('click',false);
outC.addEventListener('click',true);
outC.addEventListener('click',function(){alert("target3");},function(){alert("target4");},false);

捕获阶段的处理函数最先执行,其次是目标阶段的处理函数,最后是冒泡阶段的处理函数目标阶段的处理函数,先注册的先执行,后注册后执行

(outC的函数执行阶段 就是 目标阶段)

阻止事件冒泡和捕获



    

当点击outC的时候,之后打印出capture–>target,不会打印出bubble。

因为当事件传播到outC上的处理函数时,通过stopPropagation阻止了事件(捕获/冒泡都能阻止)的继续传播,所以不会继续传播到冒泡阶段。



    

执行结果是只打印capture,不会打印target和bubble。

注意即使阻止事件传播,目标阶段的处理函数(目标outC上的捕获/冒泡)(其实捕获/冒泡含义生效是建立在该元素有子元素的基础上,否则outC上的捕获/冒泡本质只是几个处理函数)仍旧会全部执行完毕。

停止传播(Stopping Propagation)

可以通过调用事件对象的stopPropagation方法,在任何阶段(捕获阶段或者冒泡阶段)中断事件的传播。此后,事件不会在后面传播过程中的经过的节点上调用任何的监听函数

调用event.stopPropagation()不会阻止当前节点上此事件其他的监听函数调用

如果你希望阻止当前节点上的其他回调函数调用的话,你可以使用更激进的event.stopImmediatePropagation()方法。(目标阶段,也是立即结束,不再执行同级其他回调函数)

阻止浏览器默认行为(preventDefault())

当特定事件发生的时候,浏览器会有一些默认的行为作为反应。最常见的事件不过于link被点击。当一个click事件在一个元素上被触发时,它会向上冒泡直到DOM结构的最外层document,浏览器会解释href属性,并且在窗口中加载新地址的内容

在web应用中,开发人员经常希望能够自行管理导航(navigation)信息,而不是通过刷新页面。为了实现这个目的,我们需要阻止浏览器针对点击事件的默认行为,而使用我们自己的处理方式。这时,我们就需要调用event.preventDefault().

stop/prevent区别

调用preventDefault()我们可以阻止浏览器的很多其他默认行为。比如,我们可以在HTML5游戏中阻止敲击空格时的页面滚动行为,或者阻止文本选择框的点击行为。
调用event.stopPropagation()只会阻止传播链中后续的回调函数被触发。它不会阻止浏览器的自身的行为。

猜你在找的程序笔记相关文章