skip to content

JavaScript: Replacing anchor links with JavaScript

 Tweet0 Shares0 Tweets

Anchors in HTML are essentially bookmarks within a page that can be targeted directly by adding an anchor reference starting with '#' to the URL. The browser will then jump to the specified anchor.

However when a link targets an anchor on the same page the browser 'Back' button will no longer take the browser back to the previous page, but to the previous anchor.

What is an anchor

There are two ways of marking anchor points on the page. The old method is to use the <a> tag with a name attribute. It's a bit awkward as you can see:

<h2><a name="some-heading"></a>Some Heading</h2> <h2><a name="another-heading">Another Heading</a></h2>

The more recent technique is to assign an id where you want the anchor:

<h2 id="some-heading">Some Heading</h2>

In either case we can send the browser to that section of the page by appending the anchor to the URL using a hash (#):

http://www.example.com/some-page.html#some-heading

For linking to an anchor on the same page we use:

<a href="#some-heading">Click here to jump to Some Heading</a> <a href="#another-heading">Click here to jump to Another Heading</a>

An id value must be unique on the page and start with a letter. It can then contain numbers, dashes and underscores. Colons and periods are also permissable, but can cause problems with certain JavaScript libraries.

Jumping to anchors with JavaScript

While less common now there is a simple technique for jumping to anchor points using a SELECT input for navigation. It requires just a touch of JavaScript:

<form action="#" onsubmit="return false;"> <select onchange="self.location.href = '#' + options[selectedIndex].value;"> <option>-- jump navigation --</option> <option value="some-heading">Some Heading</option> <option value="another-heading">Another Heading</option> </select> </form>

The result, which can be nicely styled using CSS, is the following:

You will see that when an option is selected the browser jumps to a new anchor point on the page and the anchor (#) appears in the URL.

A pure JavaScript solution

In all the above examples the browser is taken to different parts of the page my modifiying the URL, and this makes the 'Back' button behaviour less intuitive.

What if we could keep the benefits of using anchor points, but remove the drawback of polluting the browser history?

The solution is to use the scrollIntoView method which is supported in all major browsers. It scrolls to the (any) selected element without changing the URL.

document.getElementById("some-heading").scrollIntoView(true);

We still need to mark the anchor points using an id, but now the browser history remains unaffected.

Applying this to the SELECT navigation we end up with:

<form action="#" onsubmit="return false;"> <select onchange="document.getElementById(options[selectedIndex].value).scrollIntoView(true);"> <option>-- jump navigation --</option> <option value="some-heading">Some Heading</option> <option value="another-heading">Another Heading</option> </select> </form>

The behaviour is the same, only that the browser URL stays the same.

Applying a polyfill

The following code will parse your HTML page and override the function of any links that target anchor points on the same page. The link function will be replaced with a call to the scrollIntoView method of the target element:

<script type="text/javascript"> // Original JavaScript code by Chirp Internet: www.chirp.com.au // Please acknowledge use of this code by including this header. document.addEventListener("DOMContentLoaded", function() { var links = document.getElementsByTagName("A"); for(var i=0; i < links.length; i++) { if(!links[i].hash) continue; if(links[i].origin + links[i].pathname != self.location.href) continue; (function(anchorPoint) { links[i].addEventListener("click", function(e) { anchorPoint.scrollIntoView(true); e.preventDefault(); }, false); })(document.getElementById(links[i].hash.replace(/#/, ""))); } }, false); </script>

On page load the function loops through all links (<A>) on the page looking for those that have a hash in the target address AND that point to the current page (self.location.href).

We add an onclick event that overrides the default browser behaviour. The script assumes that all anchor points have been marked up using the id technique.

You can see the effect on these two links. They are marked up as normal links, but when the page loads our script 'upgrades' them:

Unlike before, you can trigger these links as often as you want, but the Back button will still go to the previous page and not the previous anchor point you've visited.

Extra code will be required to support IE8, as usual, and you might want to check that the target id actually exists before assigning the new handler to a link.

References

< JavaScript

Send a message to The Art of Web:


used only for us to reply, and to display your gravatar.

CAPTCHA

<- copy the digits from the image into this box

press <Esc> or click outside this box to close

User Comments

Post your comment or question

20 April, 2016

Hi. will this work within html email as an anchor alternative. Especially with the iOS8 and above..?

top