~ 事件对象

事件被触发时,会调用事件处理函数并传入一些信息,这些信息代表了当前事件的状态,即事件对象。

换句话说,当调用事件处理函数时,引擎会传入一个对象,对象就含有了事件的状态和信息。


获取事件对象

在触发DOM上的某个事件时,会产生一个事件对象event,这个对象中包含着所有与事件有关的信息。

  • 一般地,event对象是事件程序的第一个参数。    // IE8-浏览器不支持
// IE8-浏览器输出undefined,其他浏览器则输出事件对象[object MouseEvent]

   <div id="box"></div>
   <script>
      var oBox = document.getElementById('box');
      oBox.onclick = function(a){
          box.innerHTML = a;
      }
   </script>
  • 另一种方法是直接使用event变量。    // Firefox浏览器不支持
// firefox浏览器输出undefined,其他浏览器则输出事件对象[object MouseEvent] 
 
   <div id="box"></div>
   <script>
      var oBox = document.getElementById('box');
      oBox.onclick = function(){
          // box.innerHTML = event;
          box.innerHTML = window.event;    // 兼容:IE低版本中event对象通常不是通过函数传入的,而是放在window对象上
      }
   </script>

[ 兼容 ] 对于获取事件对象的常见兼容写法为:

<div id="box"></div>
<script>
   var oBox = document.getElementById('box');
   oBox.onclick = function(e){
       e = e || window.event;     
       box.innerHTML = e;
   }
</script>

属性和方法

编程中会用到事件对象中的一些属性和方法,事件对象包含与创建它的特定事件有关的属性和方法。

触发的事件类型不一样,可用的属性和方法也不一样,不过,所有事件都有些共有的属性和方法。


[1] e.type 事件类型?↓

<div id="box"></div>
<script>
   // 鼠标移入时,显示mouseover;移出时,显示mouseout;点击时,显示click
   var oBox = document.getElementById('box');
   oBox.onclick = oBox.onmouseout =oBox.onmouseover =function(e){
       e = e || window.event;
       box.innerHTML = e.type;
   }
</script>

[2] e.eventPhase    事件的阶段                               // IE8-浏览器不支持

该属性返回一个整数值,表示事件目前所处的事件流阶段,其中:

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

<button id="test" style="height: 30px;width: 200px;"></button>
<script>
test.onclick = function(e){
    e = e || window.event;
    test.innerHTML = e.eventPhase;
}
</script>

[3] 事件目标

  • e.currentTarget       // IE8-浏览器不支持

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

一般地,currentTarget与事件中的this指向相同。但在attachEvent()事件处理程序中,this指向window。

<style>
.in{height: 30px;background-color: lightblue;margin:0 10px;}
</style>
<ul id="box">
    <li class="in">1</li>
    <li class="in">2</li>
</ul>
<script>
box.onclick = function(e){
    e = e || window.event;
    var tags =  box.getElementsByTagName('li');
    tags[0].innerHTML = e.currentTarget;
    tags[1].innerHTML = (e.currentTarget === this);
}
</script>

  • e.target    // IE8-浏览器不支持

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

  • e.srcElement    // 同target,但Firefox浏览器不支持
以下代码中,点击该实际目标节点时,颜色变品红;移出时,颜色变浅蓝。

<style>
#box{background-color: lightblue;}
.in{height: 30px;}
</style>
<ul id="box">
    <li class="in">1</li>
    <li class="in">2</li>
</ul>
<script>
box.onclick = function(e){
    e = e || window.event;
    e.target.style.backgroundColor = 'pink';
}
box.onmouseout = function(e){
    e = e || window.event;
    e.target.style.backgroundColor = 'lightblue';
}
</script>

[ 兼容处理 ]

var handler = function(e){
    e = e || window.event;
    var target = e.target || e.srcElement;
}

[4] 事件冒泡

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

关于冒泡,事件对象中包含bubbles、cancelBubble、stopPropagation()和stopImmediatePropagation() 4 个属性和方法。

  • e.bubbles(只读)     返回一个布尔值,表示当前事件是否会冒泡

发生在文档元素上的大部分事件都会冒泡(true),但focus、blur和scroll事件不会冒泡(false)。

<button id="test" style="height: 30px;width: 200px;"></button>
<script>
//点击按钮时,按钮内容为true,说明click事件默认可冒泡
test.onclick = function(e){
    test.innerHTML =e.bubbles;//true
}
</script>

  • e.stopPropagation()   取消事件的进一步捕获或冒泡,无返回值       // IE8-浏览器不支持
<button id="test" style="height: 30px;width: 200px;"></button>
<script>
//点击按钮时,按钮内容为'button',因为阻止了<button>向<body>的冒泡
test.onclick = function(e){
    e = e || window.event;
    e.stopPropagation();
    test.innerHTML +='button\n';
}
document.body.onclick = function(e){
    test.innerHTML += 'body\n'
}
</script>

  • e.stopImmediatePropagation()    // IE8-浏览器不支持

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

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

<button id="test" style="height: 30px;width: 200px;"></button>
<script>
//使用stopImmediatePropagation()方法,<button>内部变为'button',且背景颜色不变
test.addEventListener('click',function(e){
    e = e || window.event;
    e.stopImmediatePropagation();
    test.innerHTML +='button\n';    
})
test.addEventListener('click',function(e){
    e = e || window.vent;
    test.style.background = 'lightblue';    
})
document.body.onclick = function(e){
    test.innerHTML += 'body\n'
}
</script>

  • e.cancelBubble               // 可读写,默认值是false

该属性只能用于阻止冒泡,无法阻止捕获。当设置为true时,cancelBubble可以取消事件冒泡。

// 该属性全浏览器支持,但并不是标准写法

<button id="test" style="height: 30px;width: 200px;"></button>
<script>
test.onclick = function(e){
    e = e || window.event;
    e.cancelBubble = true;
    test.innerHTML +='button\n';
}
document.body.onclick = function(e){
    test.innerHTML += 'body\n'
}
</script>

当使用stopIPropagation()或stopImmediatePropagation()时,cancelBubble值的变化,各浏览器表现不同。

// chrome/safari/opera中,cancelBubble的值为false
// IE9+/firefox中,cancelBubble的值为true
<button id="test" style="height: 30px;width: 200px;"></button>
<script>
test.onclick = function(e){
    e = e || window.event;
    e.stopPropagation();
    test.innerHTML = e.cancelBubble;
}
</script>

// 兼容处理

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

[5] 阻止默认行为

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

关于取消默认行为的属性包括cancelable、defaultPrevented、preventDefault()和returnValue

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

  • e.cancelable(只读)       // 返回一个布尔值,表示事件是否可以取消。true,表示可以取消。
<a id="test" href="#">链接</a>
<script>
test.onclick= function(e){
    e = e || window.event;
    test.innerHTML = e.cancelable;
}
</script>

// IE8-浏览器不支持

  • e.preventDefault()        取消浏览器对当前事件的默认行为,无返回值                   // IE8-浏览器不支持
<a id="test" href="http://www.cnblogs.com">链接</a>
<script>
test.onclick= function(e){
    e = e || window.event;
    e.preventDefault();
}
</script>
  • returnValue  可读写,默认是true,将其设置为false就可以取消事件的默认行为,同,preventDefault()
注意,firefox和IE9+浏览器不支持

// 兼容
var handler = function(e){
    e = e || window.event;
    if(e.preventDefault){
        e.preventDefault();
    }else{
        e.returnValue = false;
    }
}
  • return false    除了以上方法外,取消默认事件还可以使用return false
<a id="test" href="http://www.baidu.com">链接</a>
<script>
test.onclick= function(e){
    return false;
}
</script>
  • defaultPrevented   表示默认行为是否被阻止,返回true时表示被阻止,返回false时,表示未被阻止
// IE8-浏览器不支持

<a id="test" href="http://www.baidu.com">链接</a>
<script>
test.onclick= function(e){
    e = e || window.event;
    if(e.preventDefault){
        e.preventDefault();
    }else{
        e.returnValue = false;
    }
    test.innerHTML = e.defaultPrevented;
}
</script>