一文详解js中的事件对象、事件源对象和事件流

1. 事件对象

在JavaScript中,事件对象指的是由浏览器自动生成的包含事件相关信息的对象,它会在事件被触发时被创建。我们可以通过接收该对象作为函数参数,来获取一些事件相关的数据,例如鼠标的位置、键盘输入等。通过事件对象,我们可以在JavaScript中动态地响应用户的行为,实现交互,增加用户体验。

事件对象有许多属性和方法,下面介绍一些常用的属性:

type:事件类型,例如"click"、"keydown"、"load"等。

target:事件发生的对象,也就是事件的目标。例如点击一个按钮,target就是被点击的按钮元素。

currentTarget:当前事件绑定的对象,也就是正监听该事件的对象。在事件冒泡或捕获过程中,这个值可能会改变。

preventDefault():阻止事件的默认行为。例如,在点击链接时,如果不希望浏览器跳转到链接所指定的页面,可以通过调用这个方法来阻止默认行为。

stopPropagation():阻止事件的冒泡或捕获行为。如果不希望父元素或祖先元素接收到这个事件,可以通过调用这个方法来终止事件传递。

1.1 事件对象的获取

当一个事件被触发时,浏览器会自动创建一个事件对象,我们可以通过绑定事件的回调函数的参数来获取这个事件对象。例如:

document.addEventListener('click', function(event) {

console.log(event.target); // 打印事件的目标元素

});

在上面的例子中,click事件被触发时,浏览器会创建一个事件对象,并将其传递给回调函数作为参数。我们通过打印event.target来获取这个事件的目标元素。

1.2 阻止默认行为和阻止事件传递

在某些情况下,我们可能不希望事件的默认行为发生,或者不希望事件传递到父元素或祖先元素。这时,可以使用preventDefault()和stopPropagation()方法来阻止事件的默认行为和阻止事件传递。例如:

// 阻止链接的默认行为

document.querySelector('a').addEventListener('click', function(event) {

event.preventDefault(); // 阻止默认行为

console.log('链接被点击了!');

});

// 阻止冒泡

document.querySelector('#outer').addEventListener('click', function(event) {

console.log('outer被点击了!');

event.stopPropagation(); // 阻止冒泡

});

document.querySelector('#inner').addEventListener('click', function(event) {

console.log('inner被点击了!');

});

上面的代码演示了如何阻止链接的默认行为和阻止事件在#inner和#outer元素之间传递。

2. 事件源对象

事件源对象指的是触发事件的对象,或者说是事件的来源。如果一个按钮被点击,那么按钮就是这个事件的源。我们可以通过事件对象的target属性来获取事件源对象。例如:

document.addEventListener('click', function(event) {

console.log(event.target.nodeName); // 打印事件源对象的标签名

});

上面的代码演示了如何获取事件源对象的标签名。

2.1 事件委托

使用事件委托机制,可以将事件处理程序统一绑定到祖先元素上,以减少事件处理程序的数量和提高性能。事件委托是在捕获或冒泡阶段触发的,通过判断事件的target属性来确定事件源对象。这种机制的优点是可以在创建动态元素时,无需再次绑定事件,只需将事件绑定到父元素上。例如:

// 给container下面的所有button元素绑定click事件

document.getElementById('container').addEventListener('click', function(event) {

if (event.target.nodeName === "BUTTON") {

console.log('你点击了一个按钮!');

}

});

上面的代码演示了如何使用事件委托机制,只需要将click事件绑定到#container元素上,然后在回调函数里判断事件源对象是否是按钮。如果是按钮,执行相应的操作。

3. 事件流

在JavaScript中,事件流指的是从页面中接收和处理事件的方式。有两种事件流模型:冒泡和捕获。两种模型的区别在于事件触发的顺序不同。

3.1 冒泡模型

冒泡模型是浏览器默认的事件流模型,在冒泡模型中,事件从最内层的元素开始,逐步向外层元素传递,直到传递到最外层的元素。例如:

document.querySelector('#inner').addEventListener('click', function(event) {

console.log('inner被点击了!');

});

document.querySelector('#outer').addEventListener('click', function(event) {

console.log('outer被点击了!');

});

document.addEventListener('click', function(event) {

console.log('document被点击了!');

});

当#inner元素被点击时,事件会按照以下顺序传递:

inner

outer

document

正是由于冒泡模型的事件传递顺序,使得我们可以通过向父元素绑定事件来实现事件委托。

3.2 捕获模型

捕获模型与冒泡模型相反,在捕获模型中,事件从最外层元素开始传递,逐步向内层元素传递,最后到达最内层的元素。我们可以通过设置addEventListener方法的第三个参数来指定事件流模型,默认为false,即冒泡模型,如果设置为true,则为捕获模型。例如:

document.querySelector('#inner').addEventListener('click', function(event) {

console.log('inner被点击了!');

}, true);

document.querySelector('#outer').addEventListener('click', function(event) {

console.log('outer被点击了!');

}, true);

document.addEventListener('click', function(event) {

console.log('document被点击了!');

}, true);

当#inner元素被点击时,事件会按照以下顺序传递:

document

outer

inner

在实际开发中,我们可以根据具体的需求,选择合适的事件流模型。