2023-08-26 23:11:05
要使第二个resize事件监听器优先执行(即使代码顺序靠后),可通过设置addEventListener的第三个参数capture为true,使其在事件捕获阶段触发,从而优先于默认冒泡阶段的监听器。
具体实现步骤:默认行为分析默认情况下,addEventListener的第三个参数(useCapture)为false,事件监听器在冒泡阶段执行。若两个监听器均未设置capture,则按代码书写顺序执行(后注册的后执行)。
window.addEventListener("resize", () => console.log('默认优先级(冒泡阶段)'));window.addEventListener("resize", () => console.log('期望优先级(冒泡阶段)'));// 输出顺序:默认优先级 → 期望优先级利用捕获阶段优先执行将第二个监听器的capture参数设为true,使其在捕获阶段触发。由于捕获阶段先于冒泡阶段,第二个监听器会优先执行。
window.addEventListener("resize", () => console.log('默认优先级(冒泡阶段)'));window.addEventListener("resize", () => console.log('期望优先级(捕获阶段)'), true);// 输出顺序:期望优先级 → 默认优先级捕获阶段(从上到下):从window向目标元素传播。
目标阶段:事件到达目标元素。
冒泡阶段(从下到上):从目标元素向window传播。
false(默认):监听器在冒泡阶段执行。
true:监听器在捕获阶段执行。
若需更灵活的优先级控制(如多监听器按特定顺序执行),可结合以下方法:
自定义优先级参数通过封装addEventListener,添加优先级参数(如priority),内部按优先级排序后注册。
function addPriorityListener(event, callback, priority = 0) { // 假设存在全局数组存储监听器 window.eventListeners = window.eventListeners || []; window.eventListeners.push({ event, callback, priority }); // 按优先级排序后重新注册(需动态管理)}手动触发顺序在第一个监听器中手动调用第二个监听器(不推荐,耦合度高)。
const listener2 = () => console.log('期望优先级');window.addEventListener("resize", () => { console.log('默认优先级'); listener2(); // 强制优先执行});总结:通过设置capture: true是最简洁的解决方案,利用浏览器事件流的天然特性实现优先级控制,无需改动代码顺序或引入复杂逻辑。