3

I have a table with many rows, this table is bound in a div which had a fixed height, so I get a scroll-bar for my table. Now how can I find out which rows are in view?

I have unique ids given to each row. I am not using any library, so looking for a solution in pure JavaScript and IE

I have a button on the page whose onclick should tell me if the row is scrolled in view or not

function check()
{     
var row5 = document.getElementById("r5");
var b = document.getElementById("boundary");            
    if(!NeedThisFunction(row5,b))
        alert("not in view");
    else
        alert("in view");
    }


<button  onclick="check()" >Check</button >    
<div id="boundary" style="overflow:scroll;height:100px">
    <table border="1" >
    <tr id="r1">
    <td>row 1 col1</td>
    <td>row 1 col2</td>
    <td>row 1 col3</td>
    <td>row 1 col4</td>
    </tr>
    ...
    <tr id="r100">
    <td>row 100 col1</td>
    <td>row 100 col2</td>
    <td>row 100 col3</td>
    <td>row 100 col4</td>
    </tr>
    </table>
    </div>
Nitin Chaudhari
  • 1,497
  • 16
  • 39

1 Answers1

3

Using the accepted answer from How to tell if a DOM element is visible in the current viewport? and modifying it, you can use something like this:

function isElementInViewport(par, el) {
    var elRect = el.getBoundingClientRect(),
        parRect = par.getBoundingClientRect();
    return (
        elRect.top >= parRect.top &&
        elRect.left >= parRect.left &&
        elRect.bottom <= parRect.bottom &&
        elRect.right <= parRect.right
    );
}

function check() {
    var container = document.getElementById("boundary"),
        tr = container.getElementsByTagName("tr"),
        visible = [],
        i, j, cur;
    for (i = 0, j = tr.length; i < j; i++) {
        cur = tr[i];
        if (isElementInViewport(container, cur)) {
            visible.push(cur.id);
        }
    }
    console.log("Visible rows:", visible.join(", "));
}

function addEvent(element, eventName, callback) {
    if (element.addEventListener) {
        element.addEventListener(eventName, callback, false);
    } else if (element.attachEvent) {
        element.attachEvent("on" + eventName, callback);
    }
}

addEvent(window, "load", function () {
    addEvent(document.getElementById("check_btn"), "click", check);
    addEvent(document.getElementById("boundary"), "scroll", check);
});

DEMO: http://jsfiddle.net/jpQBU/3/

Depending on how strict you want to be, you can change the comparisons. As it stands, the element must fully be viewable. So if you scroll just a pixel too far so you can't see a tiny part of a row, it won't include it.

Community
  • 1
  • 1
Ian
  • 50,146
  • 13
  • 101
  • 111
  • Error : "Object doesn't support this property or method" at tr = container.querySelectorAll("tr"). I am using IE and no JS library – Nitin Chaudhari Jun 08 '13 at 17:36
  • @NitinChaudhari I see, sorry about that. I'm actually not sure why I used it...there's another method that does exactly what's needed and is supported better in browsers. It's just not supported in IE older than version 8. Are you on IE 7? I'll update the answer in a minute – Ian Jun 08 '13 at 17:38
  • @NitinChaudhari Awesome, glad you got it working too :) – Ian Jun 08 '13 at 17:49
  • can you update the solution to log the in view rows when the scroll ends? – Nitin Chaudhari Jun 08 '13 at 18:02
  • @NitinChaudhari Sure thing, just updated. You can add an event for the window's `scroll` event too, if you need to. – Ian Jun 08 '13 at 18:08
  • scroll event fires everytime I touch the scroll bar, I am looking for something that can tell me when scrolling ends - either by mouse up or mouse wheel stop or scroll button click – Nitin Chaudhari Jun 08 '13 at 18:24