Skip to content

Instantly share code, notes, and snippets.

@snit-ram
Created August 29, 2012 16:48
Show Gist options
  • Save snit-ram/3515501 to your computer and use it in GitHub Desktop.
Save snit-ram/3515501 to your computer and use it in GitHub Desktop.
Javascript code to hide elements from a list when scrolling. This is designed to improve performance on native scrolling lists for iphone/ipad.
/**
* Hides all elements that are outside the scrolling viewport to improve
* performance.
*
* You'll need to call this function whenever dom nodes are inserted or removed
* in the list.
*
* You'll need to declare the "unload" class in your css file as following:
* .unload { visibility: hidden; }
*
* @param Node scrollEl the dom node that has the scrollbars
* @param NodeList scrollItems a list of the scrolling items
* @param Number itemHeight the height of each item in the list
*/
function hideElementsWhenScrolling(scrollEl, scrollItems, itemHeight) {
var i,
len = scrollItems.length,
item,
containerTop = scrollEl.offsetTop,
containerHeight = scrollEl.offsetHeight,
itemsPerPage = Math.ceil(containerHeight / itemHeight),
scrollTop = scrollEl.scrollTop,
lastFirstEl = 0;
for (i = 0; i < len; i++) {
item = scrollItems[i];
item._offsetTop = item.offsetTop - containerTop;
item._offsetBottom = item._offsetTop - containerTop + itemHeight;
if (item._offsetBottom < scrollTop || item._offsetTop > scrollTop + containerHeight) {
item.classList.add('unload');
} else {
item.classList.remove('unload');
}
}
function doScrollShow(scrollTop) {
var firstEl = Math.floor(scrollTop / itemHeight),
isGoingUp = firstEl >= lastFirstEl,
i;
if (isGoingUp) {
for (i = lastFirstEl; i < firstEl; i++) {
scrollItems[i].classList.add('unload');
}
for (i = Math.min(lastFirstEl + itemsPerPage, len - 1); i < Math.min(firstEl + itemsPerPage + 1, len); i++) {
scrollItems[i].classList.remove('unload');
}
} else {
for (i = lastFirstEl; i >= firstEl; i--) {
scrollItems[i].classList.remove('unload');
}
for (i = Math.min(lastFirstEl + itemsPerPage, len - 1); i > Math.min(firstEl + itemsPerPage, len); i--) {
scrollItems[i].classList.add('unload');
}
}
lastFirstEl = firstEl;
}
function showTo(scrollTop, newScrollTop) {
var firstEl = Math.floor(scrollTop / itemHeight),
isGoingUp = newScrollTop > scrollTop,
lastEl,
i;
if (isGoingUp) {
lastEl = Math.min(Math.floor(newScrollTop / itemHeight) + itemsPerPage * 2, len);
for (i = firstEl; i < lastEl; i++) {
scrollItems[i].classList.remove('unload');
}
} else {
lastEl = Math.max(Math.floor(newScrollTop / itemHeight) - itemsPerPage * 2, 0);
for (i = lastEl; i < firstEl; i++) {
scrollItems[i].classList.remove('unload');
}
}
lastFirstEl = firstEl;
}
function onscroll() {
doScrollShow(scrollEl.scrollTop);
}
scrollEl.onscroll = onscroll;
scrollEl.ontouchmove = function (e) {
scrollEl._lastY = scrollEl._y;
scrollEl._lastT = scrollEl._t;
scrollEl._y = e.pageY;
scrollEl._t = e.timeStamp;
};
scrollEl.ontouchend = function (e) {
var deltaT = scrollEl._t - scrollEl._lastT,
deltaS = scrollEl._y - scrollEl._lastY,
V = deltaS / deltaT,
K = 278.4434180138568,
endPos = K * -V + scrollEl.scrollTop;
if (!isNaN(K * -V + scrollEl.scrollTop)) {
showTo(scrollEl.scrollTop, endPos);
}
};
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment