Javascript inline onclick goto local anchor
I need some javascript in an onclick where when click it will navigate to a local anchor. For example:
onclick="document.location=#goToPage';return false;"
Yes, the reason is I’m using JQuery Mobile which automatically adds classes to
See also stackoverflow.com/q/41624778/32453 if you’re using jQuery (or wanted to do it the truly manual way by setting top location), also includes that you can «animate down» to it or what not, FWIW.
4 Answers 4
The solution presented in the accepted answer has the important issue that it can only be used 1 time. Each consecutive click appends #goToPage to location and the window won’t navigate to the anchor.
A solution is to remove the anchor part before appending a new anchor:
function goToAnchor(anchor)
NOTE: The anchor needs to be enclosed in quotes, without the hash prefix.
@Nelu prevents the default browser behavior from taking place. In this case, it’s important because some browsers will refresh the page when clicking on a hyperlink. The modern way of doing this is event.preventDefault()
it looks the onClick should be:
onclick="document.location+='#goToPage';return false;"
See Tivie’s answer below. It points out that this answer can only be used once. After that, it just appends an additional #tag at the end of the URL and doesn’t do anything.
Wrap it in an anchor tag. You don’t need to use JS.
Can’t do it this way as it’s jquery mobile and when I add the
Just got a downvote on this however it still seems to be the most appropriate answer after 6 years. Not sure why people feel the need to overcomplicate this with JS. Just because OP asked for JS solution doesn’t mean others are incorrect. More to the point, see @foz’s comment for why the JS requirement is not necessary.
Also doesn’t work with some frameworks like bootstrap buttons which require you to use href=. for «something else» but still a good answer in many cases 🙂
How do I scroll to an element using JavaScript?
visibility and display are used for making elements (in)visible. Do you want to scroll the div in the screen?
What kind of focus? The same focus as you have when tabbing through form elements or focus in the sense of highlighting the element somehow? The only thing you do is to do display the element, which has not effect if it is already displayed.
20 Answers 20
scrollIntoView works well:
document.getElementById("divFirst").scrollIntoView();
@CameronMcCluskie it’s only the weird «scrollIntoViewOptions» (smooth scrolling, etc) that has exclusive firefox support. the basic use i have in my answer should work on almost anything.
When using this solution and you have a fixed navbar at the top, you need to consider that as well. A different solution might be more suitable such as windows.scrollTo(posX, posY) with properly calculated posY.
You can use an anchor to «focus» the div. I.e:
and then use the following javascript:
// the next line is required to work around a bug in WebKit (Chrome / Safari) location.href = "#"; location.href = "#myDiv";
Chrome (WebKit) has a bug which causes the page not to scroll once the anchor is set. Use: location.href=»#»;location.href=»#myDiv» . Using id=»myDiv» is preferred over name=»myDiv» and works too.
I had this exact problem, but the WebKit «fix» causes a problem for me in FF 3.6.13. It works without the «#» line, but if you add it, it goes to «#» and never attempts going to «#myDiv». I’ll stick with the solution without the «#», which is working for me. woohoo!
This doesn’t work well for me because it adds all of these navigation events to the browser history and I can’t easily go back to the previous page
I think ‘AnhSirk Dasarp’ below is a better method to scroll desired element to the top of the visible screen.
For Chrome and Firefox
I’ve been looking a bit into this and I figured this one out which somehow feels like the most natural way to do it. Of course, this is my personal favorite scroll now. 🙂
const y = element.getBoundingClientRect().top + window.scrollY; window.scroll(< top: y, behavior: 'smooth' >);
For IE, old Edge and old Safari supporters
Note that window.scroll(< . options >) is not supported on IE, Edge and Safari. In that case it’s most likely best to use element.scrollIntoView() . (Supported on IE 6). You can most likely (read: untested) pass in options without any side effects.
These can of course be wrapped in a function that behaves according to which browser is being used.
I wanted to take your solution, as it is possible to fine tune the position (in my case y-80). It seems, as var element = document.getElementById(«Div»); is missing in your example? Further it don’t work with IE11. IE11 don’t know window.scrollY — we have to use window.pageYOffset instead to receive a value. After I have changed that, I had various (not to comprehend) jquery errors (of course — as mostly — only in IE11. Therfore, I have implemented document.getElementById(«divFirst»).scrollIntoView(); and then $(window).scrollTop($(window).scrollTop() — 80); what works with all Browsers.
The best, shortest answer that what works even with animation effects:
var scrollDiv = document.getElementById("myDiv").offsetTop; window.scrollTo(< top: scrollDiv, behavior: 'smooth'>);
If you have a fixed nav bar, just subtract its height from top value, so if your fixed bar height is 70px, line 2 will look like:
Explanation: Line 1 gets the element position Line 2 scroll to element position; behavior property adds a smooth animated effect
Really cool, but doesn’t yet work on Safari and some other browsers. Does work with this polyfill github.com/iamdustan/smoothscroll though. 😉
We can implement by 3 Methods:
«automatic-scroll» => The particular element
«scrollable-div» => The scrollable area div
document.querySelector('.automatic-scroll').scrollIntoView(< behavior: 'smooth' >);
location.href = "#automatic-scroll";
Important notice: method 1 & method 2 will be useful if the scrollable area height is «auto«. Method 3 is useful if we using the scrollable area height like «calc(100vh — 200px)«.
You can set focus to element. It works better than scrollIntoView
Oh man, you saved my day. Tested lots of stuff but this one was the only thing that worked for me and it’s supported any all the browsers. Btw I created an input and gave 1px height and width and did focus on the input.it works great. Thanks
actually it’s a bad approaching for accessibility, and you cannot add smooth animation. i would try using window.scrollTo, but it might be error-prone on react apps since your component wont scroll due to its in another screen element, such as ‘root’, or whatever. the best here would be using scrollIntoView. although it doesn’t work on iOS currently.
var divFirst = document.getElementById("divFirst"); divFirst.style.visibility = 'visible'; divFirst.style.display = 'block'; divFirst.tabIndex = "-1"; divFirst.focus();
I only want to emphasize that the DOM property is element.tabIndex but not element.tabindex ; the second one works on Firefox but not on Chrome (at least when I tried it some time ago). Of course, used as an HTML attribute both tabIndex and tabindex work (and on XHTML, tabindex must be used)
Here’s a function that can include an optional offset for those fixed headers. No external libraries needed.
function scrollIntoView(selector, offset = 0)
You can grab the height of an element using JQuery and scroll to it.
var headerHeight = $('.navbar-fixed-top').height(); scrollIntoView('#some-element', headerHeight)
Update March 2018
Scroll to this answer without using JQuery
scrollIntoView('#answer-44786637', document.querySelector('.top-bar').offsetHeight)
To scroll to a given element, just made this javascript only solution below.
EPPZScrollTo.scrollVerticalToElementById('signup_form', 20);
Engine object (you can fiddle with filter, fps values):
/** * * Created by Borbás Geri on 12/17/13 * Copyright (c) 2013 eppz! development, LLC. * * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * */ var EPPZScrollTo = < /** * Helpers. */ documentVerticalScrollPosition: function() < if (self.pageYOffset) return self.pageYOffset; // Firefox, Chrome, Opera, Safari. if (document.documentElement && document.documentElement.scrollTop) return document.documentElement.scrollTop; // Internet Explorer 6 (standards mode). if (document.body.scrollTop) return document.body.scrollTop; // Internet Explorer 6, 7 and 8. return 0; // None of the above. >, viewportHeight: function() < return (document.compatMode === "CSS1Compat") ? document.documentElement.clientHeight : document.body.clientHeight; >, documentHeight: function() < return (document.height !== undefined) ? document.height : document.body.offsetHeight; >, documentMaximumScrollPosition: function() < return this.documentHeight() - this.viewportHeight(); >, elementVerticalClientPositionById: function(id) < var element = document.getElementById(id); var rectangle = element.getBoundingClientRect(); return rectangle.top; >, /** * Animation tick. */ scrollVerticalTickToPosition: function(currentPosition, targetPosition) < var filter = 0.2; var fps = 60; var difference = parseFloat(targetPosition) - parseFloat(currentPosition); // Snap, then stop if arrived. var arrived = (Math.abs(difference) // Filtered position. currentPosition = (parseFloat(currentPosition) * (1.0 - filter)) + (parseFloat(targetPosition) * filter); // Apply target. scrollTo(0.0, Math.round(currentPosition)); // Schedule next tick. setTimeout("EPPZScrollTo.scrollVerticalTickToPosition("+currentPosition+", "+targetPosition+")", (1000 / fps)); >, /** * For public use. * * @param id The id of the element to scroll to. * @param padding Top padding to apply above element. */ scrollVerticalToElementById: function(id, padding) < var element = document.getElementById(id); if (element == null) < console.warn('Cannot find element with id \''+id+'\'.'); return; >var targetPosition = this.documentVerticalScrollPosition() + this.elementVerticalClientPositionById(id) - padding; var currentPosition = this.documentVerticalScrollPosition(); // Clamp. var maximumScrollPosition = this.documentMaximumScrollPosition(); if (targetPosition > maximumScrollPosition) targetPosition = maximumScrollPosition; // Start animation. this.scrollVerticalTickToPosition(currentPosition, targetPosition); > >;
Get next / previous element using JavaScript?
However in some browsers (I forget which) you also need to check for whitespace and comment nodes:
var div = document.getElementById('foo2'); var nextSibling = div.nextSibling; while(nextSibling && nextSibling.nodeType != 1)
Libraries like jQuery handle all these cross-browser checks for you out of the box.
nextSibling and previousSibling (should) always return all nodes, not just element nodes shouldn’t they? This includes text nodes, comment nodes, etc. Your second example looks like a good solution for this! Maybe you could cut down on the repetition with a do <> while(); loop? (edit: or recursion perhaps)
Note that neither nextSibling nor nextElementSibling are fully cross browser compatible. Firefox’s nextSibling returns text nodes while IE doesn’t and nextElementsibling is not implemented until IE9.
@Kloar: The question asked how to get the «next [div] element in html.» The next div in the markup might not be adjacent to the element; it might be a level deeper or a level higher.
Its quite simple. Try this instead:
let myReferenceDiv = document.getElementById('mydiv'); let prev = myReferenceDiv.previousElementSibling; let next = myReferenceDiv.nextElementSibling;
Really depends on the overall structure of your document.
it may be as simple as traversing through using
mydiv.nextSibling; mydiv.previousSibling;
However, if the ‘next’ div could be anywhere in the document you’ll need a more complex solution. You could try something using
document.getElementsByTagName("div");
and running through these to get where you want somehow.
If you are doing lots of complex DOM traversing such as this I would recommend looking into a library such as jQuery.
Well in pure javascript my thinking is that you would first have to collate them inside a collection.
var divs = document.getElementsByTagName("div"); //divs now contain each and every div element on the page var selectionDiv = document.getElementById("MySecondDiv");
So basically with selectionDiv iterate through the collection to find its index, and then obviously -1 = previous +1 = next within bounds
Please be aware though as I say that extra logic would be required to check that you are within the bounds i.e. you are not at the end or start of the collection.
This also will mean that say you have a div which has a child div nested. The next div would not be a sibling but a child, So if you only want siblings on the same level as the target div then definately use nextSibling checking the tagName property.