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
在实际开发中,我们可以根据具体的需求,选择合适的事件流模型。