按键控制横向滚动:如何计算文档滚动尺寸以居中选中元素
Hey there! Let's work through this horizontal scroll centering problem together. I see you've got a solid starting idea, but let's refine the calculations to get that selected element perfectly centered in the viewport.
First, let's clear up the definitions of each value (I noticed your note about dx and wx having a 0 <= 0 range — that's probably a typo, so let's set things straight):
currentScrollLeft: The current horizontal scroll position of the document (this is what you calleddx; it's a non-negative value since you can't scroll left beyond the start of the document)viewportMidpoint: The horizontal center of the window (yourwx, which is simplywindow.innerWidth / 2)elementWidth: The width of your selected element (ex)elementDocumentOffset: The total distance of the selected element from the left edge of the entire document (this is the key value you might have overlooked!)
The Correct Centering Formula
To get the target scroll position that aligns the element's center with the viewport's center, use this formula:
const targetScrollLeft = elementDocumentOffset - viewportMidpoint + (elementWidth / 2);
Let's break this down:
elementDocumentOffsettells us where the element starts relative to the entire document.- Subtracting
viewportMidpointmoves that starting point to the middle of the viewport — but this would align the element's left edge with the viewport center. - Adding half the element's width shifts the scroll position back, so the center of the element lines up perfectly with the viewport's center.
How to Get These Values in JavaScript
Here's how to reliably fetch each variable:
currentScrollLeft: Usewindow.scrollXordocument.documentElement.scrollLeftviewportMidpoint:window.innerWidth / 2elementWidth:selectedElement.offsetWidth(includes padding and border; useclientWidthif you only want the content width)elementDocumentOffset: For elements inside nested containers,getBoundingClientRect()is the most reliable way to calculate this:const elementRect = selectedElement.getBoundingClientRect(); const elementDocumentOffset = elementRect.left + window.scrollX;
Applying the Scroll
Once you have targetScrollLeft, you can apply it with either instant or smooth scrolling:
// Instant scroll window.scrollTo({ left: targetScrollLeft }); // Smooth animated scroll window.scrollTo({ left: targetScrollLeft, behavior: 'smooth' });
Quick Note on Your Original Idea
Your initial formula (result = dx + wx - ex) was missing two critical pieces: the element's actual position in the document, and the adjustment for half the element's width. Without these, you'd end up scrolling to a position that doesn't properly center the element.
内容的提问来源于stack exchange,提问作者ZiTAL

