views:

33

answers:

1

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.

+1  A: 

Since your data is sorted, you could get to O(log(N)) with a slightly modified binary search that returns based on threshold instead of exact match. However, I doubt that searching those 12 items is what is slowing you down, since you're not doing anything expensive like DOM lookups. You should use a javascript profiler like Firebug's to see where the slowdown is actually occurring.

sunetos
Seems like nobody has a better solution than this, and/or not many people are interested in this question. A BST is a good idea and I'll implement it soon, I was hoping there was a smart way to make this constant, or at least sometimes constant. I'll give it a couple days and if nobody else has a solution, I'll accept your answer.
Jesse Dhillon
Sounds good. In the meantime, you should post your results from running the profiler.
sunetos
I'm using Ext and the profiler shows a bunch of Ext specific stuff. When I said that the scroll is slow, I meant that in my experience, the scroll event in any browser produces a somewhat slow response. This was more of a "I wonder if I'm doing this wrong" sort of question, or maybe preemptive optimization (bad!). Thanks for your answer.
Jesse Dhillon