I’m trying to achieve this but with my limited knowledge and chatgpt couldn’t solve it.
Goal:
Multiple divs that hold long contents that needs to be scrolled, when page is loaded, all divs will be scrolled to certain positions. As all divs have different contents, scrolls are different.
Here’s a sample with Figma
https://www.figma.com/proto/pTRoxhdX3MkT5A5ZHw1WPA/StackOverflow-Question?page-id=0%3A1&type=design&node-id=1-27&viewport=1194%2C529%2C1.2&t=Nb3hRH4d6spTln8C-1&scaling=min-zoom&starting-point-node-id=1%3A26&mode=design
What I have achieved:
I was able to create auto-scrolling with scroll event. Here’s the sample code I created. It has both triggers, one with DOMContentLoaded and one with scroll.
// Function to reset scroll position for a specific scrollable element
function resetScrollPosition(scrollable) {
const targetItemId = 'current';
// Scroll to the target item within the scrollable element
const targetItem = document.querySelector(`#${targetItemId}`);
if (targetItem && scrollable.contains(targetItem)) {
// Scroll to the target item if it's within the scrollable element
targetItem.scrollIntoView({ behavior: "smooth", block: "center", inline: "nearest" });
}
}
// Add scroll event listener to each scrollable element
document.addEventListener("DOMContentLoaded", () => {
const scrollables = document.querySelectorAll('.scrollable');
const timeouts = {}; // Object to store the timeout for each scrollable element
scrollables.forEach(scrollable => {
resetScrollPosition(scrollable);
// Add scroll event listener to each scrollable element
scrollable.addEventListener('scroll', () => {
// Log a message to the console to check if the scroll event listener is triggered
// Clear the previous timeout for this scrollable element
clearTimeout(timeouts[scrollable.id]);
// Set a new timeout to reset scroll position after 5 seconds of inactivity
timeouts[scrollable.id] = setTimeout(() => {
resetScrollPosition(scrollable);
}, 1000); // Adjust the timeout duration as needed
});
});
});
https://jsfiddle.net/haayany/n45Lbfd2/
However, as you can see in the title of the sample, the it does not move all divs’ scrolls when it’s loaded, but the first div only.
I was able to try it in a slightly different way, and this new one only moves the last one when the page is loaded.
document.addEventListener("DOMContentLoaded", () => {
const scrollables = document.querySelectorAll('.scrollable');
const timeouts = {}; // Object to store the timeout for each scrollable element
// Function to reset scroll position for a specific scrollable element
function resetScrollPosition(scrollable) {
// Replace 'targetItemId' with the ID of the item you want to scroll to
const targetItemId = 'current';
// Scroll to the target item within the scrollable element
const targetItem = scrollable.querySelector(`#${targetItemId}`);
if (targetItem) {
// Scroll to the calculated position within the scrollable element
targetItem.scrollIntoView({ behavior: "smooth", block: "center", inline: "nearest" });
}
}
// Add scroll event listener to each scrollable element
scrollables.forEach(scrollable => {
scrollable.addEventListener('scroll', () => {
// Clear the previous timeout for this scrollable element
clearTimeout(timeouts[scrollable.id]);
// Set a new timeout to reset scroll position after 5 seconds of inactivity
timeouts[scrollable.id] = setTimeout(() => {
resetScrollPosition(scrollable);
}, 5000); // Adjust the timeout duration as needed
});
});
// Call resetScrollPosition for each scrollable element once DOM content is loaded
scrollables.forEach(scrollable => {
resetScrollPosition(scrollable);
});
});
https://jsfiddle.net/haayany/0tmv4bkw/
I’m not sure how to update this properly to make it happen.
2
Answers
Updated it using async. it starts from the last div, but I think that's fine...
I think because the other element already in view. You can not use scrollIntoView. What I am thinking is to scroll each of the parent as much as the offset top of the current from it’s parent element.