Visible elements in a scrollable area (pure JavaScript)
by rplantiko
HTML
<div id="container" class='list'>
<table>
<tr>
<td>item</td>
</tr>
<tr>
<td>item</td>
</tr>
<tr>
<td>item</td>
</tr>
<tr>
<td>item</td>
</tr>
<tr>
<td>item</td>
</tr>
<tr>
<td>item</td>
</tr>
<tr>
<td>item</td>
</tr>
<tr>
<td>item</td>
</tr>
<tr>
<td>item</td>
</tr>
<tr>
<td>item</td>
</tr>
<tr>
<td>item</td>
</tr>
</table>
</div>
<div>
Fully enclosed rows: <input id="result" type="text" size="30">
</div>
CSS
.list {
height: 112px;
width: 300px;
display: block;
overflow-y: scroll;
margin-bottom:1em;
}
table tr td {
width: 300px;
height: 50px;
background-color: red;
border: 1px solid #000;
}
JavaScript
(function(){
var result = document.getElementById("result");
var container = document.getElementById("container");
var cells = toArray(
document.getElementsByTagName("td")
);
var isCellVisible = isChildElementVisible( container );
container.addEventListener("scroll",determineVisibleRows);
determineVisibleRows();
function determineVisibleRows() {
result.value =
cells.filter( isCellVisible ).map( rowIndex ).join(',');
}
function isChildElementVisible(container) {
var containerHeight = parseInt(getComputedStyle(container).height);
return function(element) {
var containerTop = parseInt( container.scrollTop );
var containerBottom = containerTop + containerHeight;
var elemTop = element.offsetTop;
var elemHeight = parseInt(getComputedStyle(element).height);
var elemBottom = elemTop + elemHeight;
return (elemTop >= containerTop &&
elemBottom <= containerBottom);
}
}
function toArray(arraylikeObject) {
return Array.prototype.slice.call( arraylikeObject, 0 )
}
function rowIndex( cell ) {
return cell.parentNode.rowIndex+1;
}
})()