频道栏目
首页 > 资讯 > HTML/CSS > 正文

原始事件模型、DOM2事件模型、停止事件冒泡和阻止事件的默认行为讲解

17-11-20        来源:[db:作者]  
收藏   我要投稿

原始事件模型

在原始事件模型中(也有说DOM0级),事件发生后没有传播的概念,没有事件流。事件发生,马上处理,完事,就这么简单。监听函数只是元素的一个属性值,通过指定元素的属性值来绑定监听器。书写方式有两种:

HTML代码中指定属性值:

<input type=”button” onclick=”func1()” />

在js代码中指定属性值:

document.getElementsByTagName(‘input’)[0].onclick = func1

优点:所有浏览器都兼容

缺点:

逻辑与显示没有分离; 相同事件的监听函数只能绑定一个,后绑定的会覆盖掉前面的,如:a.onclick = func1; a.onclick = func2;将只会执行func2中的内容。 无法通过事件的冒泡、委托等机制(后面系列会讲到)完成更多事情。

DOM2事件模型

此模型是W3C制定的标准模型,既然是标准,那大家都得按这个来,我们现在使用的现代浏览器(指IE6~8除外的浏览器)都已经遵循这个规范。W3C制定的事件模型中,一次事件的发生包含三个过程:

(1)capturing phase:事件捕获阶段。事件被从document一直向下传播到目标元素,在这过程中依次检查经过的节点是否注册了该事件的监听函数,若有则执行。

(2)target phase:事件处理阶段。事件到达目标元素,执行目标元素的事件处理函数.

(3)bubbling phase:事件冒泡阶段。事件从目标元素上升一直到达document,同样依次检查经过的节点是否注册了该事件的监听函数,有则执行。

这里写图片描述

所有的事件类型都会经历captruing phase但是只有部分事件会经历bubbling phase阶段,例如submit事件就不会被冒泡。

<div id = 'outer' style = 'margin: 100px 0 0 100px; width: 200px;height: 200px; background: red;'>
    <div id="inner" style = 'margin-left:20px; width: 50px;height:50px; background: green;'></div>
</div>

假设我们点击了ID为inner的div,那么此时的事件流程就是,首先执行捕获阶段:document-html-body-div(outer)。然后执行冒泡阶段:div(inner)-div(outer)-body-html-document

DOM2级的注册事件和解除事件

在DOM2级中使用addEventListener和removeEventListener来注册和解除事件(IE8及之前版本不支持)。这种函数较之之前的方法好处是一个dom对象可以注册多个相同类型的事件,不会发生事件的覆盖,会依次的执行各个事件函数。

addEventListener(‘事件名称’,’事件回调’,’捕获/冒泡’)。

示例如下:

<div id = 'outer' style = 'margin: 100px 0 0 100px; width: 200px;height: 200px; background: red;'>
    <div id="inner" style = 'margin-left:20px; width: 50px;height:50px; background: green;'></div>
</div>
<script>
    var click = document.getElementById('inner');
    click.addEventListener('click',function(){
        alert('click one');
    },false);
    click.addEventListener('click',function(){
        alert('click two');
    },false);
</script>

首先我们要知道addEventListenr的第一个参数是事件名称,与DOM0级不同的是没有”on“,另外第三个参数代表捕获还是冒泡,true代表捕获事件,false代表冒泡事件。

而在这段代码中,我们为inner的div注册了两个click事件函数,结果是浏览器会依次执行这两个函数。
  
我们在开发的时候需要兼顾IE与非IE浏览器,所以注册一个监听器应该这样写:

var a = document.getElementById('a');
if(a.attachEvent){
    a.attachEvent('onclick',func);
}
else{
    a.addEventListener('click',func,false);
}

停止事件冒泡和阻止事件的默认行为

停止事件冒泡

停止事件冒泡是指,停止冒泡型事件的进一步传递(取消事件传递,不只是停止IE和DOM标准共有的冒泡型事件,我们还可以停止支持DOM标准浏览器的捕捉型事件,用stopPropagation()方法)。例如上图中的冒泡型事件传递中,在body处理停止事件传递后,位于上层的document的事件监听器就不再收到通知,不再被处理。

在IE下,通过设置event对象的cancelBubble为true即可。
function someHandle() {
   window.event.cancelBubble = true;
 }
DOM标准通过调用event对象的stopPropagation()方法即可。
function someHandle(event) {
   event.stopPropagation();
 }
因此,跨浏览器的停止事件传递的方法是:
function someHandle(event) {
   event = event || window.event;
   if(event.stopPropagation){
     event.stopPropagation();
   }else {
     event.cancelBubble = true;
   }
 }

阻止事件的默认行为

停止事件的默认行为是指,通常浏览器在事件传递并处理完后会执行与该事件关联的默认动作(如果存在这样的动作)。例如,如果表单中input type 属性是 “submit”,点击后在事件传播完浏览器就自动提交表单。又例如,input 元素的 keydown 事件发生并处理后,浏览器默认会将用户键入的字符自动追加到 input 元素的值中。

在IE下,通过设置event对象的returnValue为false即可。
function someHandle() {
   window.event.returnValue = false;
 }
DOM标准通过调用event对象的preventDefault()方法即可。
function someHandle(event) {
   event.preventDefault();
 }
因此,跨浏览器的取消事件传递后的默认处理方法是:
function someHandle(event) {
   event = event || window.event;
   if(event.preventDefault){
     event.preventDefault();
   }else{
     event.returnValue = false;
   }
 }

总结

完整的事件处理兼容性函数
var EventUtil = {
    addHandler: function(element, type, handler){
      if (element.addEventListener){
        element.addEventListener(type, handler, false);
      } else if (element.attachEvent){
        element.attachEvent("on" + type, handler);
      } else {
        element["on" + type] = handler;
      }
   },
   removeHandler: function(element, type, handler){
     if (element.removeEventListener){
       element.removeEventListener(type, handler, false);
     } else if (element.detachEvent){
       element.detachEvent("on" + type, handler);
     } else {
       element["on" + type] = null;
     }
   },
   getEvent: function(event){
     return event ? event : window.event;
        },
   getTarget: function(event){
     return event.target || event.srcElement;
   },
   preventDefault: function(event){
     if (event.preventDefault){
       event.preventDefault();
     } else {
       event.returnValue = false;
     }
   },
   stopPropagation: function(event){
     if (event.stopPropagation){
       event.stopPropagation();
     } else {
       event.cancelBubble = true;
     }
 };
相关TAG标签
上一篇:Bootstrap框架使用介绍
下一篇:用canvas画转动的阴阳鱼(代码教程)
相关文章
图文推荐

关于我们 | 联系我们 | 广告服务 | 投资合作 | 版权申明 | 在线帮助 | 网站地图 | 作品发布 | Vip技术培训 | 举报中心

版权所有: 红黑联盟--致力于做实用的IT技术学习网站