在触发 DOM 上的某个事件时,会产生一个事件对象 event,这个对象中包含着所有与事件有关的信息。所有浏览器都支持 event 对象,但支持方式不同。本文将详细介绍事件对象
【1】一般地,event 对象是事件程序的第一个参数
[注意]IE8 - 浏览器不支持
- //IE8-浏览器输出undefined,其他浏览器则输出事件对象[object MouseEvent]
- < div id = "box"style = "height:30px;width:200px;background:pink;" > </div>
- <script>
- var oBox = document.getElementById('box');
- oBox.onclick = function(a){
- box.innerHTML = a;
- }
- </script >
【2】另一种方法是直接使用 event 变量
[注意]firefox 浏览器不支持
- //firefox浏览器输出undefined,其他浏览器则输出事件对象[object MouseEvent]
- < div id = "box"style = "height:30px;width:200px;background:pink;" > </div>
- <script>
- var oBox = document.getElementById('box');
- oBox.onclick = function(){
- box.innerHTML = event;
- }
- </script >
兼容
于是,对于获取事件对象的常见兼容写法如下
- <div id="box" style="height:30px;width:200px;background:pink;">
- </div>
- <script>
- var oBox = document.getElementById('box');
- oBox.onclick = function(e) {
- e = e || event;
- box.innerHTML = e;
- }
- </script>
事件对象包含与创建它的特定事件有关的属性和方法。触发的事件类型不一样,可用的属性和方法也不一样。不过,所有事件都有些共有的属性和方法
事件有很多类型,事件对象中的 type 属性表示被触发的事件的类型
- <div id="box" style="height:30px;width:200px;background:pink;">
- </div>
- <script>
- //鼠标移入时,显示mouseover;移出时,显示mouseout;点击时,显示click
- var oBox = document.getElementById('box');
- oBox.onclick = oBox.onmouseout = oBox.onmouseover = function(e) {
- e = e || event;
- box.innerHTML = e.type;
- }
- </script>
通过点击或按 tab 键将焦点切换到 button 按钮上可以触发 focus 事件
- <button id="box" style="height:30px;width:200px;background:pink;">
- </button>
- <script>
- var oBox = document.getElementById('box');
- oBox.onfocus = function(e) {
- e = e || event;
- box.innerHTML = e.type;
- }
- </script>
关于事件目标,共有 currentTarget、target 和 srcElement 这三个属性
currentTarget
currentTarget 属性返回事件当前所在的节点,即正在执行的监听函数所绑定的那个节点
[注意]IE8 - 浏览器不支持
一般地,currentTarget 与事件中的 this 指向相同。但在 attachEvent() 事件处理程序中,this 指向 window,
.in">
- . in "><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 || event;
- var tags = box.getElementsByTagName('li');
- tags[0].innerHTML = e.currentTarget;
- tags[1].innerHTML = (e.currentTarget === this);
- }
- </script>"
target
currentTarget 属性返回事正在执行的监听函数所绑定的节点,而 target 属性返回事件的实际目标节点
[注意]IE8 - 浏览器不支持
以下代码中,点击该实际目标节点时,颜色变品红;移出时,颜色变浅蓝
#bo">
- #bo "><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 || event;
- e.target.style.backgroundColor = 'pink';
- }
- box.onmouseout = function(e){
- e = e || event;
- e.target.style.backgroundColor = 'lightblue';
- }
- </script>"
srcElement
srcElement 属性与 target 属性功能一致
[注意]firefox 浏览器不支持
#bo">
- #bo "><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 || event;
- e.srcElement.style.backgroundColor = 'pink';
- }
- box.onmouseout = function(e){
- e = e || event;
- e.srcElement.style.backgroundColor = 'lightblue';
- }
- </script>"
兼容
- var handler = function(e) {
- e = e || event;
- var target = e.target || e.srcElement;
- }
由于事件会在向上传播到父节点,因此可以把子节点的监听函数定义在父节点上,由父节点的监听函数统一处理多个子元素的事件。这种方法叫做事件的代理 (delegation)
事件代理应用事件目标的 target 和 srcElement 属性完成。利用事件代理,可以提高性能及降低代码复杂度
有一个需求,一个 <ul> 中有 5 个 <li>,移入时变浅蓝,移出时变品红
下面分别用常规方法和事件代理方法来实现
- #box {
- background - color: pink;
- }. in {
- height: 30px;
- }
- 1 2 3 4 5
- //常规方法
- var tags = box.getElementsByTagName('li');
- for (var i = 0; i < tags.length; i++) {
- tags[i].onmouseover = function(e) {
- this.style.backgroundColor = 'lightblue';
- }
- tags[i].onmouseout = function(e) {
- this.style.backgroundColor = 'pink';
- }
- }
- //事件代理方法
- box.onmouseover = function(e) {
- e = e || event;
- var target = e.target || e.srcElement;
- target.style.backgroundColor = 'lightblue';
- }
- box.onmouseout = function(e) {
- e = e || event;
- var target = e.target || e.srcElement;
- target.style.backgroundColor = 'pink';
- }
事件冒泡是的第三个阶段,通过事件冒泡可以在这个阶段对事件做出响应
关于冒泡,事件对象中包含 bubbles、cancelBubble、stopPropagation() 和 stopImmediatePropagation() 这四个相关的属性和方法
bubbles
bubbles 属性返回一个布尔值,表示当前事件是否会冒泡。该属性为只读属性
发生在文档元素上的大部分事件都会冒泡,但 focus、blur 和 scroll 事件不会冒泡。所以,除了这三个事件 bubbles 属性返回 false 外,其他事件该属性都为 true
- <button id="test" style="height: 30px;width: 200px;">
- </button>
- <script>
- //点击按钮时,按钮内容为true,说明click事件默认可冒泡
- test.onclick = function(e) {
- test.innerHTML = e.bubbles; //true
- }
- </script>
- <div id="test" style="height: 50px;width: 200px;overflow:scroll;background:pink;line-height:60px;">
- 内容
- </div>
- <script>
- //滚动时,div内容变成false,说明scroll事件默认不可冒泡
- test.onscroll = function(e) {
- test.innerHTML = e.bubbles; //false
- }
- </script>
stopPropagation()
stopPropagation() 方法表示取消事件的进一步捕获或冒泡,无返回值
[注意]IE8 - 浏览器不支持
- <button id="test" style="height: 30px;width: 200px;">
- </button>
- <script>
- //点击按钮时,按钮内容为'button',因为阻止了<button>向<body>的冒泡
- test.onclick = function(e) {
- e = e || event;
- e.stopPropagation();
- test.innerHTML += 'button\n';
- }
- document.body.onclick = function(e) {
- test.innerHTML += 'body\n'
- }
- </script>
stopImmediatePropagation()
stopImmediatePropagation() 方法不仅可以取消事件的进一步捕获或冒泡,而且可以阻止同一个事件的其他监听函数被调用,无返回值
[注意]IE8 - 浏览器不支持
使用 stopIPropagation() 方法,可以阻止冒泡,但无法阻止同一事件的其他监听函数被调用
- <button id="test" style="height: 30px;width: 200px;">
- </button>
- <script>
- //使用stopIPropagation()方法,<button>内部变为'button',且背景颜色变成浅蓝
- test.addEventListener('click',
- function(e) {
- e = e || event;
- e.stopPropagation();
- test.innerHTML += 'button\n';
- }) test.addEventListener('click',
- function(e) {
- e = e || event;
- test.style.background = 'lightblue';
- }) document.body.onclick = function(e) {
- test.innerHTML += 'body\n'
- }
- </script>
使用 stopImmediatePropagation() 方法,即可以阻止冒泡,也可以阻止同一事件的其他监听函数被调用
- <button id="test" style="height: 30px;width: 200px;">
- </button>
- <script>
- //使用stopImmediatePropagation()方法,<button>内部变为'button',且背景颜色不变
- test.addEventListener('click',
- function(e) {
- e = e || event;
- e.stopImmediatePropagation();
- test.innerHTML += 'button\n';
- }) test.addEventListener('click',
- function(e) {
- e = e || event;
- test.style.background = 'lightblue';
- }) document.body.onclick = function(e) {
- test.innerHTML += 'body\n'
- }
- </script>
cancelBubble
cancelBubble 属性只能用于阻止冒泡,无法阻止捕获阶段。该值可读写,默认值是 false。当设置为 true 时,cancelBubble 可以取消事件冒泡
[注意] 该属性全浏览器支持,但并不是标准写法
- <button id="test" style="height: 30px;width: 200px;">
- </button>
- <script>
- test.onclick = function(e) {
- e = e || 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 || event;
- e.stopPropagation();
- test.innerHTML = e.cancelBubble;
- }
- </script >
兼容
- 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,表示处于目标阶段
- <button id="test" style="height: 30px;width: 200px;">
- </button>
- <script>
- test.onclick = function(e) {
- e = e || event;
- test.innerHTML = e.eventPhase;
- }
- </script>
【2】以下代码返回 1,表示处于捕获阶段
- <button id="test" style="height: 30px;width: 200px;">
- </button>
- <script>
- document.addEventListener('click',
- function(e) {
- e = e || event;
- test.innerHTML = e.eventPhase;
- },
- true);
- </script>
【3】以下代码返回 3,表示处于冒泡阶段
- <button id="test" style="height: 30px;width: 200px;">
- </button>
- <script>
- document.addEventListener('click',
- function(e) {
- e = e || event;
- test.innerHTML = e.eventPhase;
- },
- false);
- </script>
常见的默认行为有点击链接后,浏览器跳转到指定页面;或者按一下空格键,页面向下滚动一段距离
关于取消默认行为的属性包括 cancelable、defaultPrevented、preventDefault() 和 returnValue
点击下列锚点时,会自动打开博客园首页
<a id="test" href="http://www.cnblogs.com" target="_blank"> 链接 </a>cancelable
cancelable 属性返回一个布尔值,表示事件是否可以取消。该属性为只读属性。返回 true 时,表示可以取消。否则,表示不可取消
[注意]IE8 - 浏览器不支持
<a id="test" href="#"> 链接 </a> <script> test.onclick= function(e){ e = e || event; test.innerHTML = e.cancelable; } </script>preventDefault()
preventDefault() 方法取消浏览器对当前事件的默认行为,无返回值
[注意]IE8 - 浏览器不支持
<a id="test" href="http://www.cnblogs.com"> 链接 </a> <script> test.onclick= function(e){ e = e || event; e.preventDefault();} </script>returnValue
returnValue 属性可读写,默认值是 true,但将其设置为 false 就可以取消事件的默认行为,与 preventDefault() 方法的作用相同
[注意]firefox 和 IE9 + 浏览器不支持
<a id="test" href="http://www.cnblogs.com"> 链接 </a> <script> test.onclick= function(e){ e = e || event; e.returnValue = false; } </script>兼容
- var handler = function(e) {
- e = e || event;
- if (e.preventDefault) {
- e.preventDefault();
- } else {
- e.returnValue = false;
- }
- }
return false
除了以上方法外,取消默认事件还可以使用 return false
<a id="test" href="http://www.cnblogs.com"> 链接 </a> <script> test.onclick= function(e){ return false; } </script>defaultPrevented
defaultPrevented 属性表示默认行为是否被阻止,返回 true 时表示被阻止,返回 false 时,表示未被阻止
[注意]IE8 - 浏览器不支持
<a id="test" href="http://www.cnblogs.com"> 链接 </a> <script> test.onclick= function(e){ e = e || event; if(e.preventDefault){e.preventDefault(); }else{ e.returnValue = false; } test.innerHTML = e.defaultPrevented; } </script>来源: http://www.cnblogs.com/xiaohuochai/p/5862775.html