The Problem
As the page is scrolled from top to bottom, the user will pass through these ranges. Suppose they are values in an alphabetical address book: as they scroll from top to bottom, they will pass from A to Z. There are tabs on the side labeled with the names of sections in the document, labeled 'Aa-An', 'Am-As', etc.
What I want is, as the user scrolls from top to bottom, the scroll handler determines which of these sections is currently scrolled into and highlights the tab correlated with the current section.
In Javascript, on the document's scroll event, I need to determine whether the document's vertical scroll falls between one of a set of values. The values look like this:
var indices = {
'Aa-An': [{id: 92, name: 'Aardvark'}, {id: 13, name: 'Affable'}, ...],
'Am-As': [{id: 28, name: 'Amber'}, ...],
...
}
var heights = {
'item_92': {top: 170, bottom: 380},
'item_28': {top: 380, bottom: 600},
...
}
The keys in heights
are the id
attributes of the first element in each array in indices
. top
is the location on the page of the first element in that list, and bottom
is the location on the page of the bottom edge of the last element in that list.
The Current Solution
My scroll handler is:
var scroll = get_vertical_scroll();
for(var key in heights) {
var top = heights[key].top;
var bottom = heights[key].bottom;
if(scroll >= top && scroll < bottom) {
select('.index_tab').removeClass('selected');
get('index_'+key).addClass('selected');
return;
}
}
At most, there will only be 12 keys in heights
to iterate through, so this is an effective linear solution. But, the scroll event is already pretty slow and if there's a smart way to make this O(1) -- even in only some cases -- that would go a long way given that this happens on each scroll of the document.