9

I was searching for a way to prevent being taken to the top of a page after clicking a link with # inside the href attribute:

<a href="#" onclick="foobar()">click me</a>

and then I came across this simple solution, switching # for #!:

<a href="#!" onclick="foobar()">click me</a>

There were various other solutions available online using jQuery for instance:

$('.service').click(function(e) {
    e.preventDefault();
});

I ended up liking #! the most for being so clean BUT I COULDN'T find any documentation anywhere online as to what was actually happening when inserting the ! in the line of code.

QUESTION:

What is #! actually causing the html code to do? Is this a good way to prevent the default action of taking the user to the top of the page, or is this method bad for other reasons? What I'm afraid of is that it might be a hacky method that isn't compatible with some browsers.

Webeng
  • 7,050
  • 4
  • 31
  • 59
  • Found an answer to your question in the following post: http://stackoverflow.com/a/6349758/736172 – Ahmad Jun 05 '16 at 10:00

1 Answers1

17

What is #! actually causing the html code to do?

It's telling the browser that when that link is clicked, it should scroll the page to the anchor !. Because there is no such anchor on the page, the page doesn't move. (Technically, you could have an anchor with the name ! on the page [! is a perfectly valid HTML id value]. It's just...you probably don't.)

You create anchors on the page by assigning id values to elements (or using the outdated <a name="...">...</a> construct); hrefs with a fragment identifier (the bit following the #) tell the browser to load the resource (in your example, it's the current page, which is already loaded) and then scroll down to that anchor. So for instance, if you have <div id="foo">...</div> on a page, the navigate to #foo on that page, the browser will scroll down so that that div is showing. When you supply a non-existant anchor, no scrolling is done.

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
  • 2
    Thanks T.J. just tested it out with random letters like `href="#dsf"` and that also works, exactly like your answer illustrates – Webeng Jun 05 '16 at 10:05
  • 4
    @Webeng: Side note: `#!` used to be part of Google's [*Making AJAX applications crawlable*](https://developers.google.com/webmasters/ajax-crawling/docs/learn-more#current-practice) recommendation from 2009 (basically you did `#!foo=bar` and it told Googlebot to query a hardcoded HTML version of what that would look like); they [deprecated](https://webmasters.googleblog.com/2015/10/deprecating-our-ajax-crawling-scheme.html) that recommendation in 2015. – T.J. Crowder Jun 05 '16 at 10:17
  • good to know. I also noticed that the url contains a `#!` after clicking the link, and decided to take advantage of this feature not only to not go on the top of the page, but to give the user a fun message like `#enjoy_your_stay`, while ofcourse not having any id's called `enjoy_your_stay` on the page – Webeng Jun 05 '16 at 10:50
  • 1
    @Webeng: :-) Another option is to use `href="javascript:;"`, which does nothing at all. – T.J. Crowder Jun 05 '16 at 13:37