views:

51

answers:

4

How can I get an indication of what part of a long document is currently being displayed?

E.g. if my html contains 1,000 lines
1
2
3
...
999
1000

and the user is near the middle showing the 500th line then I would like to get "500\n501\n502" or something like that.

Obviously most scenarios would be more complex than this, but my requirement is to find which text is currently being displayed in the browser viewport so I can show a status value appropriate to the current text.

Thanks Martin

A: 

Yes, there is a way. I will use YUI's API to illustrate my example. First your text must be in some sort of dom element, whether its a span, div, p or anything, it must be in a element. Here I will assume list item

var viewPortY = YAHOO.util.Dom.getDocumentScrollTop(),
viewPortHeight = YAHOO.util.Dom.getViewportHeight(), i = 0,
// get all the dom elements that contain the text, sorry if this isn't exact, its just a rough example
items = YAHOO.util.Dom.getElementBy(null, 'li', document.getElementById('item-container')),
viewedItems = [];
    for (i = 0 ; i < items.length; i++) {
        var y = YAHOO.util.Dom.getY(items[i])
        if (y > viewPortY && y < (viewPortY + viewPortHeight)) {
           viewedItems.push(items[i])
        }
    }

So essentially, I get all the dom objects that contain the text your interested in. I then loop through, and whoever's Y co-ordinate is between the viewports Y and Y + ViewPort Height, I put in an array.

Zoidberg
Thanks for this, it would be great, but I am not using YUI's api.
Martin
A: 

You can get a value in pixels from the scrollTop property:

document.body.scrollTop = 40;

To know what part of your document that is visible, you could loop through (say) all p-tags until you find one with a negative scrollTop value. The one before that is the one at the top of the window.

geon
Thanks for the idea of iterating all tags. I used that as part of the solution but I used the offsetTop attribute so I only needed to process all tags once and store the page offset, then on scroll I iterated all offsets to find which tags were top of the viewport.
Martin
A: 

If you have jQuery, you can use this function to check if a DOM element is currently shown in the viewport:

function isInView(elem) {

    var docViewTop = $(window).scrollTop();
    var docViewBottom = docViewTop + $(window).height();

    var elemTop = $(elem).offset().top;
    var elemBottom = elemTop + $(elem).height();

    return ((elemBottom >= docViewTop) && (elemTop <= docViewBottom));
}
Philippe Leybaert
Thanks for that idea but in my scenario I am writing for a pda and like to keep the code lean so don't use jQuery, but the comparison algorithm is helpful.
Martin
Not even minified? I can't see how you can get lean code with a lot of functionality without using a framework.
Zoidberg
A: 

I marked the first answer as being the answer because I thought it was a good answer and it was the first answer, but I implemented what I thought was a more optimal solution for my environment.

I am writing for Android so I can easily interact with a Java class from javascript. My actual solution involved getting offsetTop of all tags I am interested in and passing the offsets to java.

Also registering an onscroll handler that passed window.pageYOffset throught to the same Java class. Then the java class can compare offsetTop of each tag with pageYOffset to see which tag is at the top of the current viewport.

Martin