Jon Jon - 4 months ago 18
HTML Question

Prevent DIV from scrolling on DOM content change

I am writing a document reading application using Node-Webkit. A document can be hundreds of pages long and the interface allows opening the document to a specific chapter. Once the initial chapter is displayed, I want to load the rest of the book asynchronously. Since I don't know what direction the reader will scroll, my strategy is to alternately load chapters before and then after the initial chapter:

load chapter x -> load chapter x-1 -> load chapter x+1 -> load x-2 -> load x+2 ...

I am displaying the book in a containing div element with each chapter being a div within the container. I'm using jquery .before() and .after() to insert each chapter as it is fetched.

My problem is that the browser automatically scrolls up when I add chapters earlier in the book. So if I start with chapter 10, the browser scrolls up when I add chapter 9 and again with chapter 8 and so forth.

One (unsatisfactory) solution to the problem is to make an anchor tag for each chapter and store the id of the first chapter loaded. Then after each chapter is fetched, runing the code:

window.location.href = #originalChapter

keeps the initial chapter in the browser viewport. Of course the problem with that is that the reader cannot scroll while the rest of the book is being loaded.

Ideally, I would like to disable scrolling, load a chapter and then re-enable until the next chapter is fetched. I'm so far unable to figure out how to do that.

Wex Wex

The simple solution in my mind would be to not have the elements in the DOM until they are loaded. The user won't be able to scroll because there won't be content to scroll to. Then, it's just a matter of preserving the viewport when the elements are added.

Take the initial position of your scroll container and the height of the overflow container:

var scrollTop = $scroll.scrollTop(),
    height    = $container.height();

and use them to preserve the viewport when you prepend new elements. You don't have to do anything when you're doing the append operation.

var newHeight    = $container.height(),
    newScrollTop = scrollTop + newHeight - height;

Here's a quick example: