I know a variation on this has been asked several times; I\'ve been browsing SO for a while now but either I\'m doing something wrong or I haven\'t found what I need.
<According to MDN Web Docs:
The
Element.scrollIntoViewIfNeeded()
method scrolls the current element into the visible area of the browser window if it's not already within the visible area of the browser window. If the element is already within the visible area of the browser window, then no scrolling takes place. This method is a proprietary variation of the standard Element.scrollIntoView() method.
Example (with jQuery):
$('#example')[0].scrollIntoViewIfNeeded();
Note: This feature is non-standard and is not on a standards track, so use caution before using this in production. See Can I use... for browser support.
I modified the answer from @iandisme a bit and wrapped it up as a tiny jquery plugin:
(function ($) {
'use strict';
$.fn.scrollToSimple = function ($target) {
var $container = this.first(); // Only scrolls the first matched container
var pos = $target.position(), height = $target.outerHeight();
var containerScrollTop = $container.scrollTop(), containerHeight = $container.height();
var top = pos.top + containerScrollTop; // position.top is relative to the scrollTop of the containing element
var paddingPx = containerHeight * 0.15; // padding keeps the target from being butted up against the top / bottom of the container after scroll
if (top < containerScrollTop) { // scroll up
$container.scrollTop(top - paddingPx);
}
else if (top + height > containerScrollTop + containerHeight) { // scroll down
$container.scrollTop(top + height - containerHeight + paddingPx);
}
};
})(jQuery);
I removed the calls to .animate since I was looking for instant scrolling. I also added the ability to scroll any (scrollable) container, rather than just the window. Example usage:
// scroll the window so #target is visible
$(window).scrollToSimple( $("#target") );
// scroll the scrollable element #container so that #target is visible
$("#container").scrollToSimple( $("#target") );
Had the same problem... after reviewing a few answers, here's what I came up with for doing this... without pulling down another plugin.
function scrollIntoViewIfNeeded($target) {
if ($target.position()) {
if ($target.position().top < jQuery(window).scrollTop()){
//scroll up
$('html,body').animate({scrollTop: $target.position().top});
}
else if ($target.position().top + $target.height() >
$(window).scrollTop() + (
window.innerHeight || document.documentElement.clientHeight
)) {
//scroll down
$('html,body').animate({scrollTop: $target.position().top -
(window.innerHeight || document.documentElement.clientHeight)
+ $target.height() + 15}
);
}
}
}
The "15" on the last line is just extra padding - you might need to adjust it, or add it to the scroll up line.
EDIT: changed window.innerHeight
to (window.innerHeight || document.documentElement.clientHeight)
for IE < 8 support
All modern Browsers support this. Visit: http://caniuse.com/#search=scrollIntoView
function scrollIntoViewIfNeeded(target) {
if (target.getBoundingClientRect().bottom > window.innerHeight) {
target.scrollIntoView(false);
}
if (target.getBoundingClientRect().top < 0) {
target.scrollIntoView();
}
}
Update
The target has to be an Element. If you use jQuery call the function like this:
scrollIntoViewIfNeeded($(".target")[0]);