Is there any way to position elements or some clever hack in such a way to allow for adding or removing elements from either the top or bottom of the DOM without affecting the scroll?
I've tried using Jquery to measure the length of the added/removed elements and then as soon as I add/remove them, I scroll the current container the offset amount. This successfully gets me to stay at the current position, however, I've noticed that more often than not there is a visible "jump" that occurs in the space of time it takes to first affect the content and then run the follow up scroll fix.
I imagine the best way to handle something like this would be to remove the concept of "scrolling" and somehow implement it manually, but I'm not sure how to go about doing so. Any ideas are greatly appreciated!
This should already work out-of-the-box based on the scroll anchoring spec currently implemented by Chrome and Firefox (link).
Directly from the spec introduction:
Today, users of the web are often distracted by content moving around due to changes that occur outside the viewport. Examples include script inserting an iframe containing an ad, or non-sized images loading on a slow network.
[...]
Scroll anchoring attempts to keep the user’s view of the document stable across layout changes. It works by selecting a DOM node (the anchor node) whose movement is used to determine adjustments to the scroll position.
It may not be working for you because the anchor node selected is not correct or you are using an unsupported browser (caniuse data). The exact process for the anchor node is described here. You can tweak the anchor selection algorithm by setting the CSS property overflow-anchor: none
on the nodes you want not to be the scroll anchor.
Working example for scroll anchoring: Just scroll within 5s and scroll up when the text turns red. You will see a new <p>
node added at the top.
const root = document.querySelector('#root');
const ol = document.querySelector('#list');
ol.las
setTimeout(() => {
const para = document.createElement('p');
para.innerText = 'A\nB\nC';
root.insertBefore(para, ol);
root.classList.add("red");
}, 3000);
.red {
color: red;
}
<div id="root">
<ol id="list">
<li>Hello</li><li>World!</li><li>Bye</li><li>World!</li><li>Hello</li><li>World!</li><li>Bye</li><li>World!</li><li>Hello</li><li>World!</li><li>Bye</li><li>World!</li><li>Hello</li><li>World!</li><li>Bye</li><li>World!</li><li>Hello</li><li>World!</li><li>Bye</li><li>World!</li><li>Hello</li><li>World!</li><li>Bye</li><li>World!</li><li>Hello</li><li>World!</li><li>Bye</li><li>World!</li><li>Hello</li><li>World!</li><li>Bye</li><li>World!</li><li>Hello</li><li>World!</li><li>Bye</li><li>World!</li><li>Hello</li><li>World!</li><li>Bye</li><li>World!</li><li>Hello</li><li>World!</li><li>Bye</li><li>World!</li><li>Hello</li><li>World!</li><li>Bye</li><li>World!</li><li>Hello</li><li>World!</li><li>Bye</li><li>World!</li><li>Hello</li><li>World!</li><li>Bye</li><li>World!</li><li>Hello</li><li>World!</li><li>Bye</li><li>World!</li><li>Hello</li><li>World!</li><li>Bye</li><li>World!</li><li>Hello</li><li>World!</li><li>Bye</li><li>World!</li><li>Hello</li><li>World!</li><li>Bye</li><li>World!</li><li>Hello</li><li>World!</li><li>Bye</li><li>World!</li><li>Hello</li><li>World!</li><li>Bye</li><li>World!</li><li>Hello</li><li>World!</li><li>Bye</li><li>World!</li><li>Hello</li><li>World!</li><li>Bye</li><li>World!</li><li>Hello</li><li>World!</li><li>Bye</li><li>World!</li>
</ol>
</div>
Can you share your code to see why it is not working?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With