JT2*_*809 7 safari firefox opera chromium microsoft-edge
我想使用具有平滑行为的 window.scrollTo 函数。例如:
window.scrollTo({ top: 0, behavior: 'smooth' })
Run Code Online (Sandbox Code Playgroud)
并行我想改变元素的颜色。为此,我可以使用滚动事件来计算当前滚动位置的颜色。但这会导致性能不佳,因为滚动回调会经常调用。更好的解决方案是同时开始过渡。但为此我必须知道滚动持续时间。由于无法手动定义它,我需要知道浏览器使用的持续时间。
规范说
滚动框使用用户代理定义的计时函数在用户代理定义的时间段内以平滑的方式滚动。用户代理应遵循平台约定(如果有)。
这立即使它成为一个复杂的问题,可能没有答案,或者至少没有可靠的答案。
浏览器可能
以下是一些 Firefox 代码中与平滑滚动相关的注释摘录。我没有深入研究这是否实际上与您正在做的滚动类型严格相关,但它提供了一个想法:
Run Code Online (Sandbox Code Playgroud)* |Smooth| scrolls have a symmetrical acceleration and deceleration curve * modeled with a set of splines that guarantee that the destination will be * reached over a fixed time interval. |Smooth| will only be smooth if smooth * scrolling is actually enabled. This behavior is utilized by keyboard and * mouse wheel scrolling events. * * |SmoothMsd| implements a physically based model that approximates the * behavior of a mass-spring-damper system. |SmoothMsd| scrolls have a * non-symmetrical acceleration and deceleration curve, can potentially * overshoot the destination on intermediate frames, and complete over a * variable time interval. |SmoothMsd| will only be smooth if cssom-view * smooth-scrolling is enabled.
这里有一些代码您可以用来自己测试。在我的实验中,我发现在 Firefox 和 Chromium 中,持续时间根据滚动距离而变化,而且我发现它们的速度不同。
* |Smooth| scrolls have a symmetrical acceleration and deceleration curve
* modeled with a set of splines that guarantee that the destination will be
* reached over a fixed time interval. |Smooth| will only be smooth if smooth
* scrolling is actually enabled. This behavior is utilized by keyboard and
* mouse wheel scrolling events.
*
* |SmoothMsd| implements a physically based model that approximates the
* behavior of a mass-spring-damper system. |SmoothMsd| scrolls have a
* non-symmetrical acceleration and deceleration curve, can potentially
* overshoot the destination on intermediate frames, and complete over a
* variable time interval. |SmoothMsd| will only be smooth if cssom-view
* smooth-scrolling is enabled.
Run Code Online (Sandbox Code Playgroud)
const qs = document.querySelector.bind(document);
const viewportHeightInput = qs("#viewport-height");
const contentHeightInput = qs("#content-height");
const viewport = qs("#viewport");
const content = qs("#content");
const output = qs("#output");
function update() {
viewport.style.height = `${viewportHeightInput.value}px`;
content.style.height = `${contentHeightInput.value}px`;
}
update();
viewportHeightInput.addEventListener("input", update);
contentHeightInput.addEventListener("input", update);
qs("#to-top").addEventListener("click", () => {
start = performance.now();
scrollEvents = 0;
updateScrollEvents();
viewport.scrollTo({
behavior: "smooth",
top: 0,
})
});
qs("#to-bottom").addEventListener("click", () => {
start = performance.now();
scrollEvents = 0;
updateScrollEvents();
viewport.scrollTo({
behavior: "smooth",
top: viewport.scrollHeight - viewport.clientHeight,
})
});
const scrollEventsOutput = qs("#scroll-events");
const elapsedOutput = qs("#elapsed");
let scrollEvents = 0;
let start = performance.now();
let last = null;
viewport.addEventListener("scroll", () => {
last = performance.now();
scrollEvents++;
updateScrollEvents();
});
function updateScrollEvents() {
scrollEventsOutput.value = scrollEvents;
elapsedOutput.value = last == null ? 0 : last - start;
}Run Code Online (Sandbox Code Playgroud)
#controls {
display: grid;
grid-template-columns: 10rem 1fr;
}
#controls fieldset {
display: contents;
}
#viewport {
overflow: auto;
border: thick solid orange;
margin: 4rem 0;
}
#content {
background-image: linear-gradient(to bottom left, black, white);
position: relative;
}
#content::before,
#content::after {
position: absolute;
left: 0;
background-color: black;
color: white;
display: block;
}
#content::before {
content: "start";
top: 0;
}
#content::after {
content: "end";
bottom: 0;
}Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
7966 次 |
| 最近记录: |