I've just tried prototype's scrollTo function and as the documentation states, it
Scrolls the window so that element appears at the top of the viewport
I'd like a function that
does anyone know of such a function in prototype, scriptaculous or stand-alone?
I guess you need something like this (demo):
window.height
function getWindowHeight() {
var body = document.body;
var docEl = document.documentElement;
return window.innerHeight ||
(docEl && docEl.clientHeight) ||
(body && body.clientHeight) ||
0;
}
Scroll
function scrollElemToCenter(id, duration) {
var el = document.getElementById(id);
var winHeight = getWindowHeight();
var offsetTop = el.offsetTop;
if (offsetTop > winHeight) {
var y = offsetTop - (winHeight-el.offsetHeight)/2;
// wo animation: scrollTo(0, y);
scrollToAnim(y, duration);
}
}
Animation (optional, you can use script.aculo.us, etc.)
function interpolate(source,target,pos) { return (source+(target-source)*pos); }
function easing(pos) { return (-Math.cos(pos*Math.PI)/2) + 0.5; }
function scrollToAnim(targetTop, duration) {
duration || (duration = 1000);
var start = +new Date,
finish = start + duration,
startTop = getScrollRoot().scrollTop,
interval = setInterval(function(){
var now = +new Date,
pos = (now>finish) ? 1 : (now-start)/duration;
var y = interpolate(startTop, targetTop, easing(pos)) >> 0;
window.scrollTo(0, y);
if(now > finish) {
clearInterval(interval);
}
}, 10);
}
get scroll root
var getScrollRoot = (function() {
var SCROLL_ROOT;
return function() {
if (!SCROLL_ROOT) {
var bodyScrollTop = document.body.scrollTop;
var docElScrollTop = document.documentElement.scrollTop;
window.scrollBy(0, 1);
if (document.body.scrollTop != bodyScrollTop)
(SCROLL_ROOT = document.body);
else
(SCROLL_ROOT = document.documentElement);
window.scrollBy(0, -1);
}
return SCROLL_ROOT;
};
})();
Here is an alternative approach, that uses some of Prototype's built in functionality for working with the viewport and scroll dimensions...
function scrollToCenterOfElement(id){
// Cache element and property lookups...
var element = $(id);
var height = element.measure('height');
var top = element.cumulativeOffset().top;
var scroll = document.viewport.getScrollOffsets();
var dimensions = document.viewport.getDimensions();
// Checks to see if the top offset plus the height of the element is greater
// than the sum of the viewport height and vertical scroll offset, which means
// that the element has yet to be fully scrolled in to view, or if the
// top offset is smaller than the vertical scroll offset, which means the element
// has already been (at least partly) scrolled out of view..
if ((top + height > dimensions.height + scroll.top) || (top < dimensions.height + scroll.top)) {
// Scroll window to sum of top offset plus half the height of the element
// minus half of the viewport height, thus centering the element vertically.
window.scrollTo(0, top + (height / 2) - (dimensions.height / 2));
}
}
scrollToCenterOfElement('my-element');
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With