事件之事件对象

一  定义

在 DOM 中发生事件时,所有相关信息都会被收集并存储在一个名为 event 的对象中

  • 一些基本信息,比如导致事件的元素、发生的事件类型,以及可能与特定事件相关的任何其他数据

二  DOM事件对象

1、事件对象:

  • 在DOM合规的浏览器中,以DOM0或DOM2的方式指定事件处理程序,event对象是传给事件处理程序的唯一参数
  • 事件对象包含与特定事件相关的属性和方法
  • event 对象只在事件处理程序执行期间存在,一旦执行完毕,就会被销毁
let btn = document.getElementById("myBtn"); 
btn.onclick = function(event) { 
 console.log(event.type); // "click" 
}; 
btn.addEventListener("click", (event) => { 
 console.log(event.type); // "click" 
}, false);

// 这个例子中的两个事件处理程序都会在控制台打出 event.type 属性包含的事件类型。
// 这个属性中始终包含被触发事件的类型,如"click"(与传给 addEventListener()和removeEventListener()方法的事件名一致)

2、公共属性和方法:

 

 事件处理程序添加的对象不同会造成什么影响?

  • 直接添加在意图的目标:this、currentTarget 和 target 的值是一样
    • this 对象始终等于 currentTarget 的值 
    • target 只包含事件的实际目标   
let btn = document.getElementById("myBtn"); 
btn.onclick = function(event) { 
 console.log(event.currentTarget === this); // true 
 console.log(event.target === this); // true 
}; 

// 上面的代码检测了 currentTarget 和 target 的值是否等于 this。因为 click 事件的目标是按钮,所以这 3 个值是相等的。
  • 在要操作目标元素的父节点上添加
    • this 和 currentTarget 都等于 父节点,这是因为它是注册事件处理程序的元素
    • target 属性等于按钮本身,这是因为那才是 操作事件真正的目标
// 如果这个事件处理程序是添加到按钮的父节点(如 document.body)上,那么它们的值就不一样了。比如下面的例子在 document.body 上添加了单击处理程序:
document.body.onclick = function(event) { 
 console.log(event.currentTarget === document.body); // true 
 console.log(this === document.body); // true 
 console.log(event.target === document.getElementById("myBtn")); // true 
}; 

// 这种情况下点击按钮,this 和 currentTarget 都等于 document.body,这是因为它是注册事件处理程序的元素。而 target 属性等于按钮本身,这是因为那才是 click 事件真正的目标。由于按钮本身并没有注册事件处理程序,因此 click 事件冒泡到 document.body,从而触发了在它上面注册的处理程序。

3、重点方法

  • event.type:type 属性在一个处理程序处理多个事件时很有用
let btn = document.getElementById("myBtn"); 
let handler = function(event) { 
 switch(event.type) { 
     case "click": 
         console.log("Clicked"); 
     break; 
     case "mouseover": 
         event.target.style.backgroundColor = "red"; 
     break; 
     case "mouseout": 
         event.target.style.backgroundColor = ""; 
     break; 
 } 
}; 
btn.onclick = handler; 
btn.onmouseover = handler; 
btn.onmouseout = handler; 

// 在这个例子中,函数 handler 被用于处理 3 种不同的事件:click、mouseover 和 mouseout。当按钮被点击时,应该在控制台打印一条消息,如前面的例子所示。而把鼠标放到按钮上,会导致按钮背景变成红色,接着把鼠标从按钮上移开,背景颜色应该又恢复成默认值。这个函数使用 event.type属性确定了事件类型,从而可以做出不同的响应

  • preventDefault():用于阻止特定事件的默认动作

任何可以通过 preventDefault()取消默认行为的事件,其事件对象的 cancelable 属性都会设置为 true

// 链接的默认行为就是在被单击时导航到 href 属性指定的 URL。如果想阻止这个导航行为,可以在 onclick 事件处理程序中取消

let link = document.getElementById("myLink"); 
link.onclick = function(event) { 
  event.preventDefault(); 
}; 

  • stopPropagation():用于立即阻止事件流在 DOM 结构中传播,取消后续的事件捕获或冒泡
// 直接添加到按钮的事件处理程序中调用 stopPropagation(),可以阻止 document.body 上注册的事件处理程序执行。比如:

let btn = document.getElementById("myBtn"); 
btn.onclick = function(event) { 
 console.log("Clicked"); 
 event.stopPropagation(); 
}; 
document.body.onclick = function(event) { 
 console.log("Body clicked"); 
}; 

// 如果这个例子中不调用stopPropagation(),那么点击按钮就会打印两条消息。但这里由于click事件不会传播到 document.body,因此 onclick 事件处理程序永远不会执行

  • eventPhase 属性:可用于确定事件流当前所处的阶段
    • 如果事件处理程序在捕获阶段被调用,则 eventPhase 等于 1
    • 如果事件处理程序在目标上被调用,则 eventPhase 等于 2
    • 如果事件处理程序在冒泡阶段被调用,则 eventPhase 等于 3
    • 不过要注意的是,虽然“到达目标”是在冒泡阶段发生的, 但其 eventPhase 仍然等于 2
let btn = document.getElementById("myBtn"); 
btn.onclick = function(event) { 
 console.log(event.eventPhase); // 2 
}; 
document.body.addEventListener("click", (event) => { 
 console.log(event.eventPhase); // 1 
}, true); 
document.body.onclick = (event) => { 
 console.log(event.eventPhase); // 3 
}; 

// 在这个例子中,点击按钮首先会触发注册在捕获阶段的 document.body 上的事件处理程序,显示eventPhase 为 1
// 接着,会触发按钮本身的事件处理程序(尽管是注册在冒泡阶段),此时显示 eventPhase 等于 2
// 最后触发的是注册在冒泡阶段的 document.body 上的事件处理程序,显示eventPhase 为 3
// 而当 eventPhase 等于 2 时,this、target 和 currentTarget 三者相等。

三  IE事件对象

定义:IE 事件对象可以基于事件处理程序被指定的方式以不同方式来访问

// 场景一: DOM0 方式
// 事件处理程序是使用 DOM0 方式指定的,则 event 对象只是 window 对象的一个属性,如下所示:
var btn = document.getElementById("myBtn"); 
btn.onclick = function() { 
 let event = window.event; 
 console.log(event.type); // "click" 
}; 

//这里,window.event 中保存着 event 对象,其 event.type 属性保存着事件类型(IE 的这个属性的值与 DOM 事件对象中一样)

// 场景二:IE方法
// 如果事件处理程序是使用 attachEvent()指定的,则 event对象会作为唯一的参数传给处理函数,如下所示:
var btn = document.getElementById("myBtn"); 
btn.attachEvent("onclick", function(event) { 
 console.log(event.type); // "click" 
}); 
//使用 attachEvent()时,event 对象仍然是 window 对象的属性(像 DOM0 方式那样),只是出于方便也将其作为参数传入。


//场景三:HTML
//如果是使用 HTML 属性方式指定的事件处理程序,则 event 对象同样可以通过变量 event 访问(与DOM 模型一样)。下面是在 HTML 事件属性中使用 event.type 的例子:
<input type="button" value="Click Me" onclick="console.log(event.type)"> 

1、属性方法

 2、this作用域

  • 由于事件处理程序的作用域取决于指定它的方式,因此 this 值并不总是等于事件目标
  • 不同事件对象上的 srcElement 属性中保存的都是事件目标
//更好的方式是使用事件对象的 srcElement 属性代替 this。下面的例子表明,不同事件对象上的srcElement 属性中保存的都是事件目标:
var btn = document.getElementById("myBtn"); 
btn.onclick = function() { 
 console.log(window.event.srcElement === this); // true 
}; 
btn.attachEvent("onclick", function(event) { 
 console.log(event.srcElement === this); // false 
}); 

// 在第一个以 DOM0 方式指定的事件处理程序中,srcElement 属性等于 this,而在第二个事件处理程序中(运行在全局作用域下),两个值就不相等了

3、returnValue 属性

等价于 DOM 的 preventDefault()方法,都是用于取消给定事件默认的行为

// 只不过在这里要把 returnValue 设置为 false 才是阻止默认动作。下面是一个设置该属性的例子:
var link = document.getElementById("myLink"); 
link.onclick = function() { 
 window.event.returnValue = false; 
}; 

// 在这个例子中,returnValue 在 onclick 事件处理程序中被设置为 false,阻止了链接的默认行为
// 与 DOM 不同,没有办法通过 JavaScript 确定事件是否可以被取消

4、cancelBubble 属性

与 DOMstopPropagation()方法用途一样,都可以阻止事件冒泡。因为 IE8 及更早版本不支持捕获阶段,所以只会取消冒泡。stopPropagation()则既取消捕获也取消冒泡

// 下面是一个取消冒泡的例子:
var btn = document.getElementById("myBtn"); 
btn.onclick = function() { 
 console.log("Clicked"); 
 window.event.cancelBubble = true; 
}; 
document.body.onclick = function() { 
 console.log("Body clicked"); 
}; 

// 通过在按钮的 onclick 事件处理程序中将 cancelBubble 设置为 true,可以阻止事件冒泡到document.body,也就阻止了调用注册在它上面的事件处理程序。于是,点击按钮只会输出一条消息

四 跨浏览器事件对象

定义:

  • 虽然 DOM 和 IE 的事件对象并不相同,但它们有足够的相似性可以实现跨浏览器方案
  • DOM 事件对象中包含 IE 事件对象的所有信息和能力,只是形式不同。这些共性可让两种事件模型之间的映射成为可能
var EventUtil = { 
 addHandler: function(element, type, handler) { 
     // 为节省版面,删除了之前的代码
 }, 
 getEvent: function(event) {  //其返回对 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; 
     } 
 }, 
 removeHandler: function(element, type, handler) { 
     // 为节省版面,删除了之前的代码
 }, 
 stopPropagation: function(event) { //先检测用于停止事件流的 DOM 方法,如果没有再使用 cancelBubble 属性
     if (event.stopPropagation) { 
         event.stopPropagation(); 
     } else { 
         event.cancelBubble = true; 
     } 
 } 
}; 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值