162

On my HTML page, I want to be able to 'go to' / 'scroll to' / 'focus on' an element on the page.

Normally, I'd use an anchor tag with a href="#something", but I'm already using the hashchange event along with the BBQ plugin to load this page.

So is there any other way, via JavaScript, to have the page go to a given element on the page?

Here's the basic outline of what I'm trying to do:

function focusOnElement(element_id) {
     $('#div_' + element_id).goTo(); // need to 'go to' this element
}

<div id="div_element1">
   yadda yadda 
</div>
<div id="div_element2">
   blah blah
</div>

<span onclick="focusOnElement('element1');">Click here to go to element 1</span>
<span onclick="focusOnElement('element2');">Click here to go to element 2</span>
Peter O.
  • 32,158
  • 14
  • 82
  • 96
Cuga
  • 17,668
  • 31
  • 111
  • 166
  • 4
    My honest suggestion is dropping the BBQ plugin. What a terrible idea, destroying expected default behaviour for a silly storage mechanism. – user229044 Jan 26 '11 at 05:42
  • 1
    We're using the BBQ plugin for a slideshow, which is the central feature of this page. The plugin allows us to fetch the next item via Ajax without needing to repost the rest of the page. In this case, the BBQ plugin is kind of crucial. – Cuga Jan 26 '11 at 05:57
  • 1
    if you still use StackOverflow, it might be worth updating the answer to the more popular, native one. – mikemaccana Oct 17 '17 at 11:59

4 Answers4

216

If the element is currently not visible on the page, you can use the native scrollIntoView() method.

$('#div_' + element_id)[0].scrollIntoView( true );

Where true means align to the top of the page, and false is align to bottom.

Otherwise, there's a scrollTo() plugin for jQuery you can use.

Or maybe just get the top position()(docs) of the element, and set the scrollTop()(docs) to that position:

var top = $('#div_' + element_id).position().top;
$(window).scrollTop( top );
naveen
  • 53,448
  • 46
  • 161
  • 251
user113716
  • 318,772
  • 63
  • 451
  • 440
  • 23
    +1 for the native scrollIntoView which i didnt know at all. for a moment i thought it was jquery. :) – naveen Jan 26 '11 at 06:15
  • 2
    @yetanothercode: Thanks for adding the MDN link. I was a little to lazy last night. :o) – user113716 Jan 26 '11 at 14:18
  • 6
    `position().top` is not correct because it is relative to the parent element. You shall use `offset().top` which is relative to the document. – Federico Bellucci Feb 15 '12 at 16:09
  • 1
    I combined this with the accepted answer with great results: `function($) { $.fn.goTo = function() { $(this)[0].scrollIntoView(true); return this; // for chaining... } })(jQuery);` – Marty Mulligan Apr 14 '14 at 14:14
  • Thanks for native answer !! – Peter C Apr 07 '16 at 15:23
  • Thanks for native answer, but UX of this feature is terrible. [There is even an answer](http://stackoverflow.com/a/9446004/2559709) about how bad is it. – Alex Zhukovskiy Apr 25 '16 at 14:25
  • thanks for native answer, but not very configurable where I want top-150px to center in the list – Mimouni May 19 '16 at 15:09
  • 2
    from MDN: `scrollIntoView is experimental technology` and from their compatibility only work on firefox – GusDeCooL Sep 30 '16 at 00:39
183

The standard technique in plugin form would look something like this:

(function($) {
    $.fn.goTo = function() {
        $('html, body').animate({
            scrollTop: $(this).offset().top + 'px'
        }, 'fast');
        return this; // for chaining...
    }
})(jQuery);

Then you could just say $('#div_element2').goTo(); to scroll to <div id="div_element2">. Options handling and configurability is left as an exercise for the reader.

Reigel Gallarde
  • 64,198
  • 21
  • 121
  • 139
mu is too short
  • 426,620
  • 70
  • 833
  • 800
  • 1
    One question is, why would you animate 'html, body' and not just 'body'? – Lior Oct 10 '13 at 18:24
  • 5
    @Lior: Honestly, I do that now because I've always done it that way; I think the original reason for `'html,body'` is to deal with browser differences. – mu is too short Oct 10 '13 at 18:30
  • 2
    I added a variable so that, if there was say a header that the element was still under, I can pass a negative to stop the scroll earlier: **usage:** `$('#element').goTo(-50);` **function:** `(function ($) { $.fn.goTo = function (addToScroll) { if (!addToScroll) { addToScroll = 0; } $('html, body').animate({ scrollTop: ($(this).offset().top + addToScroll) + 'px' }, 'fast'); return this; // for chaining... } })(jQuery);` – jaybro May 03 '17 at 22:51
171
document.getElementById("elementID").scrollIntoView();

Same thing, but wrapping it in a function:

function scrollIntoView(eleID) {
   var e = document.getElementById(eleID);
   if (!!e && e.scrollIntoView) {
       e.scrollIntoView();
   }
}

This even works in an IFrame on an iPhone.

Example of using getElementById: http://www.w3schools.com/jsref/tryit.asp?filename=tryjsref_document_getelementbyid

GlennG
  • 2,982
  • 2
  • 20
  • 25
  • Simple, works well in jQueryMobile where hash tags can be problematic. – matt Mar 30 '13 at 22:40
  • sweeeet. simple and works on iphone – ace Mar 09 '16 at 22:17
  • 3
    as of 2016, `scrollIntoView()` is technically non-standard ([ref](https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollIntoView)), but you can pretty much use it everywhere anyway ([ref](http://caniuse.com/#feat=scrollintoview)). – thejoshwolfe May 20 '16 at 21:11
  • `scrollIntoView()` appears to have wide support except for the "smooth" parameter according to [caniuse.com](http://caniuse.com/#feat=scrollintoview) – GlennG May 22 '16 at 10:39
  • 1
    It doesn't scroll. It just throws you on top. No any scrolling. How to animate it? – Green May 26 '16 at 06:14
  • 2
    This is a base JavaScript method and doesn't animate. However, it doesn't need a framework (e.g. JQuery) to run. If you want animation, use something like is mentioned here: http://stackoverflow.com/questions/1586341/how-can-i-scroll-to-a-specific-location-on-the-page-using-jquery – GlennG Jun 23 '16 at 09:09
  • It's important to note it has very limited support across browsers https://developer.mozilla.org/en/docs/Web/API/Element/scrollIntoView – Rafael Xavier Aug 26 '16 at 23:36
  • As answered before, limited support is for the extensions to the scrollIntoView("option") - not the basic scrollIntoView() method which is supported by all browsers. – GlennG Sep 06 '16 at 13:51
  • no need for " !! " - js if statements already check for truthiness – Rick Penabella Oct 08 '21 at 00:18
  • `!!` is a check for nulls - if `e` is null then `e.scrollIntoView()` will hurl. – GlennG Oct 08 '21 at 14:38
21

To scroll to a specific element on your page, you can add a function into your jQuery(document).ready(function($){...}) as follows:

$("#fromTHIS").click(function () {
    $("html, body").animate({ scrollTop: $("#toTHIS").offset().top }, 500);
    return true;
});

It works like a charm in all browsers. Adjust the speed according to your need.

nbro
  • 15,395
  • 32
  • 113
  • 196
lorddarq
  • 685
  • 1
  • 10
  • 17