开发者

Given a set of top/bottom pixel ranges, how do I find which one has been scrolled into?

开发者 https://www.devze.com 2023-01-08 02:53 出处:网络
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

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 w开发者_JAVA技巧ith 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.


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.

0

精彩评论

暂无评论...
验证码 换一张
取 消