gpt4 book ai didi

reactjs - React 中 `onScroll` 和 `onScrollCapture` 的区别?

转载 作者:行者123 更新时间:2023-12-05 04:25:28 25 4
gpt4 key购买 nike

React 中 onScrollonScrollCapture 有什么区别?

不确定这是 DOM 主题还是纯 JS 主题,因为我找不到任何关于 onScrollCapture 的资源。

const node = (
<div onScrollCapture={handleScrollCapture} />
);

最佳答案

onScrollCapture 在 React 中相当于做:

addEventListener('scroll', listener, { capture: true })

addEventListener('scroll', listener, true)

在原生 JS 中。

两者都说:如果事件在子元素上触发,请先运行我的处理程序(父元素),然后再运行它们的处理程序。例如,当您在下面的演示中单击按钮时,浏览器将首先运行父 div 的事件处理程序,然后再运行按钮本身的处理程序:

const parent = document.querySelector('.parent');
const button = parent.querySelector('button');

parent.addEventListener('click', () => console.log('parent'), true);
button.addEventListener('click', (e) => {
console.log('button');
});
.parent {
width: 100px;
height: 100px;
border: solid 1px black;
display: flex;
align-items: center;
justify-content: center;
}

button {
background: white;
}
<div class="parent">
<button>
Click me
</button>
</div>

传统上,在注册事件监听器时,您只需执行 addEventListener('event', listener) 而无需第三个参数(或 React 中的 onEvent={listener} ).如果事件目标是嵌套在当前元素中的子元素(如上例中的按钮),这意味着事件将:

  1. 首先在目标(按钮)上开火,然后
  2. 在该元素(父 div)在树上冒泡时触发它(假设它完全冒泡)。

这与使用 onEventCapture 及其 vanilla-JS 等效项的顺序相反。

更一般地说,所有事件都经历三个阶段:

  1. 捕获,从 DOM 树的根开始,向下追踪路径以找到实际触发事件的元素(目标)。
  2. 定位,一旦到达目标,事件就会在目标本身上触发。
  3. 冒泡,事件返回到 DOM 的根,并在沿途的每个父元素上触发。 ( If and only if the event bubbles .)

对于父元素,事件仅在冒泡或捕获阶段触发,而不是同时触发,何时它们触发由以下因素决定:

  • 事件是否完全冒泡(有些事件不会)。
  • 您是否向 addEventListener 提供了第三个参数。

重要的是,scroll 事件不会冒泡。因此,在下面的示例中,当您滚动它时,只有子 div 的消息会记录到控制台:

const parent = document.querySelector('.parent');
const child = parent.querySelector(':scope > *');

parent.addEventListener('scroll', () => console.log('parent scrolled'));
child.addEventListener('scroll', () => console.log('child scrolled'));
body {
display: flex;
justify-content: center;
align-items: center;
}

div {
border: solid 1px black;
}

.parent {
height: 250px;
overflow-y: scroll;
max-width: 200px;
display: flex;
align-items: center;
justify-content: center;
padding: 1rem;
}

.parent>* {
height: 200px;
overflow-y: auto;
}
<div class="parent">
<div tabindex="0" role="region">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin mattis augue quis turpis vestibulum volutpat a a sem. Maecenas ornare ac felis sed volutpat. Curabitur dapibus ante nec ante congue, et consectetur nunc tempor. Sed gravida posuere sollicitudin.
Etiam feugiat a nulla vel consequat. Vestibulum vel massa faucibus, rutrum felis quis, mollis orci. Vivamus vestibulum ligula non orci cursus tincidunt. Proin hendrerit tincidunt finibus. Donec vitae aliquet sem. Nunc vel purus non nunc consectetur
luctus in vel mauris. Donec varius quam risus, non lacinia orci rutrum in. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam nunc turpis, cursus sodales vulputate eu, eleifend fermentum est. Aliquam sollicitudin congue justo vitae ullamcorper.
Proin lectus mi, faucibus vitae pharetra id, fringilla sit amet arcu. Interdum et malesuada fames ac ante ipsum primis in faucibus. Ut ut ipsum nulla. Proin in aliquet purus, quis consectetur risus. Aliquam erat volutpat. Sed auctor tristique interdum.
Morbi ac purus eget leo interdum gravida at ac nunc. Donec commodo vitae quam pulvinar bibendum. Duis nunc enim, scelerisque vel maximus quis, semper eu ipsum. Nam eu mollis ante.
</div>
</div>

这意味着如果你想给父元素添加一个事件监听器并检测子元素上的滚动,那么你需要使用滚动捕获,像这样:

const parent = document.querySelector('.parent');
const child = parent.querySelector(':scope > *');

parent.addEventListener('scroll', () => console.log('parent scrolled'), true);
child.addEventListener('scroll', () => console.log('child scrolled'));
body {
display: flex;
justify-content: center;
align-items: center;
}

div {
border: solid 1px black;
}

.parent {
height: 250px;
overflow-y: scroll;
max-width: 200px;
display: flex;
align-items: center;
justify-content: center;
padding: 1rem;
}

.parent>* {
height: 200px;
overflow-y: auto;
}
<div class="parent">
<div tabindex="0" role="region">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin mattis augue quis turpis vestibulum volutpat a a sem. Maecenas ornare ac felis sed volutpat. Curabitur dapibus ante nec ante congue, et consectetur nunc tempor. Sed gravida posuere sollicitudin.
Etiam feugiat a nulla vel consequat. Vestibulum vel massa faucibus, rutrum felis quis, mollis orci. Vivamus vestibulum ligula non orci cursus tincidunt. Proin hendrerit tincidunt finibus. Donec vitae aliquet sem. Nunc vel purus non nunc consectetur
luctus in vel mauris. Donec varius quam risus, non lacinia orci rutrum in. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam nunc turpis, cursus sodales vulputate eu, eleifend fermentum est. Aliquam sollicitudin congue justo vitae ullamcorper.
Proin lectus mi, faucibus vitae pharetra id, fringilla sit amet arcu. Interdum et malesuada fames ac ante ipsum primis in faucibus. Ut ut ipsum nulla. Proin in aliquet purus, quis consectetur risus. Aliquam erat volutpat. Sed auctor tristique interdum.
Morbi ac purus eget leo interdum gravida at ac nunc. Donec commodo vitae quam pulvinar bibendum. Duis nunc enim, scelerisque vel maximus quis, semper eu ipsum. Nam eu mollis ante.
</div>
</div>

关于reactjs - React 中 `onScroll` 和 `onScrollCapture` 的区别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73249488/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com