Closed mw10013 closed 11 months ago
https://dev.to/martinez/real-scroll-for-a-chat-application-22co
function Chat() {
const [messages, setMessages] = useState<string[]>([])
const container = useRef<HTMLDivElement>(null)
const Scroll = () => {
const { offsetHeight, scrollHeight, scrollTop } = container.current as HTMLDivElement
if (scrollHeight <= scrollTop + offsetHeight + 100) {
container.current?.scrollTo(0, scrollHeight)
}
}
useEffect(() => {
Scroll()
}, [messages])
return <div ref={container}>{messages}</div>
}
https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollHeight
The Element.scrollHeight read-only property is a measurement of the height of an element's content, including content not visible on the screen due to overflow.
scrollTop is a non-rounded number, while scrollHeight and clientHeight are rounded — so the only way to determine if the scroll area is scrolled to the bottom is by seeing if the scroll amount is close enough to some threshold
Math.abs(element.scrollHeight - element.clientHeight - element.scrollTop) < 1;
https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollTop
An element's scrollTop value is a measurement of the distance from the element's top to its topmost visible content. When an element's content does not generate a vertical scrollbar, then its scrollTop value is 0.
https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/offsetHeight
The HTMLElement.offsetHeight read-only property returns the height of an element, including vertical padding and borders, as an integer.
https://developer.mozilla.org/en-US/docs/Web/API/Element/clientHeight
The Element.clientHeight read-only property is zero for elements with no CSS or inline layout boxes; otherwise, it's the inner height of an element in pixels. It includes padding but excludes borders, margins, and horizontal scrollbars (if present).
If you need to know the total amount of space an element occupies, including the width of the visible content, scrollbars (if any), padding, and border, you want to use the HTMLElement.offsetWidth and HTMLElement.offsetHeight properties.
If you need to know how much space the actual displayed content takes up, including padding but not including the border, margins, or scrollbars, you want to use the Element.clientWidth and Element.clientHeight properties
If you need to know the actual size of the content, regardless of how much of it is currently visible, you need to use the Element.scrollWidth and Element.scrollHeight properties.
https://stackoverflow.com/questions/72636816/scroll-to-bottom-when-new-message-added
The trick then lies in reversing the content direction using column-reverse in the scroller. Because the items are in another container, they don't get 'flipped' but instead always line up to the bottom. This, in fact, makes the scroller scrolled to the bottom whenever stuff is added.
whenever the user has started scrolling (up), the scroller will not lose its scroll position when stuff is being added. So, it will only 'stick' tot the bottom if it was already scrolled (by default, or by the user) to the bottom.
https://code.hnldesign.nl/scrolltobottom/
add the items to an item container which is inside a scroller container with display:flex, flex-direction: column-reverse and overflow: scroll (or auto) set.
https://web.dev/resize-observer/
https://usehooks.com/usemeasure