11

I've checked other posts on here, no results of what I'm looking for. I want to click on

<a href="#about">About</a>
<div id="about">Content of this..</div>

and have it scroll to that element without putting www.domain.com/#about in the address bar

As a perfect example please check out this site that I found here and click on some of the links --they don't change the address bar when clicked.

Fabio
  • 23,183
  • 12
  • 55
  • 64
nodebase
  • 2,510
  • 6
  • 31
  • 46

8 Answers8

3

You can do what you want using javascript and jquery, example below (note that this is using an old version of jquery):

<head>
    <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.7/jquery.min.js"></script>

    <script type='text/javascript'>
    jQuery(document).ready(function($) {

        $(".scroll").click(function(event){
            event.preventDefault();
            $('html,body').animate({scrollTop:$(this.hash).offset().top}, 1200);
        });
    });
    </script>
</head>
<body>
    <a class="scroll" href="#codeword">Blue Words</a>
    <div id="codeword"></div>
</body>
</html>
n0rman0
  • 113
  • 11
  • It's specifically the event.preventDefault(); that does it ---- without you get an annoying flash of where it ends up followed by the scrolling to that place... So not updating the URL is unintentional I think. [It's also bad I think: Arriving by hyperlink to a specific section, a naive user cannot click on another section & copy the relevant, updated URL to pass on; having scrolled elsewhere, upon refresh I'm back somewhere else.] – user3445853 Oct 22 '20 at 10:18
1

Played around with this myself and here is a summary of my learnings on the subject.

Here's the basic link command:

<A HREF="#codeword">Blue Words</A>

Here's how you denote where the jump will scroll the page:

<A NAME="codeword">

Here's what's happening

The A HREF command is the same as a basic link except the link is to a codeword rather than a URL.

PLEASE NOTICE there is a # sign in front of the codeword. You need that to denote it is an internal link. Without the # sign, the browser looks for something outside the page named after your codeword.

Your "codeword" can be just about anything you want. I try my best to keep it short and make it denote what it is jumping to. There might be a limit to the number of letters you can use--but I haven't found it yet.

The point where the page will jump follows the same general format except you will replace the word HREF with the word NAME.

PLEASE NOTICE there is no # sign in the NAME command.

Note! Where you place the NAME target will appear at the top of the screen browser.

Hope it helps.

PatGW
  • 369
  • 6
  • 19
1
window.location.hash = ""  

is the possible way I could find.

hash gives the string next to #.

Kishor Pawar
  • 3,386
  • 3
  • 28
  • 61
  • Could you please elaborate on this answer I have no idea what you mean exactly. So you have the part next to #, and then? I don't know what this has to do with keeping the URL unaffected when an anchor link is clicked. Maybe a quick example like OP? – Invest Jul 19 '19 at 07:11
  • 1
    In my case, I had to show part of the URL before the anchor, to make the URL look beautiful. So I wanted to truncate the anchor links. window.location object stores the URL parts. https://www.w3schools.com/js/js_window_location.asp . The URL patrt afther the # is assigned to window.location.hash. So I assigned empty value to it so that I can only show part of the URL. – Kishor Pawar Jul 19 '19 at 10:36
  • 1
    @Invest Could you please explain the rationale for downvote? – Kishor Pawar Jul 20 '19 at 05:25
  • As fas as I understand the question is more related to "How can I SCROLL to anchor links without showing them in the URL?" and not about actually having a nice looking URL. – Invest Jul 20 '19 at 18:10
  • 1
    Exactly @Invest, when you click on the anchor, the href is added after the # (hash). So if you do window.location.hash = "" after the anchor is clicked, the href in the URL would be replaced by empty string. Hope I am clear this time. – Kishor Pawar Jul 20 '19 at 18:21
  • Okay now I understand it better, thank you. But this is only half of the story, right? How would you implement the "scrolling to a certain point" without using the ? Or did I misunderstand your answer and you ARE using href="#about" and AFTERWARDS you do window.location.hash = "" to clear the URL? – Invest Jul 22 '19 at 11:12
  • 1
    Yes, first it scrolls the page to internal link and then you set `window.location.hash = ""`. – Kishor Pawar Jul 22 '19 at 11:14
0

//dont use a, use class

 $(document).ready(function(){
 $(".mouse").on('click', function(event) {
// Make sure this.hash has a value before overriding default behavior
  if (this.hash !== "") {
  // Prevent default anchor click behavior
  event.preventDefault();
 // Store hash
  var hash = this.hash;
 // Using jQuery's animate() method to add smooth page scroll
  // The optional number (800) specifies the number of milliseconds it takes 
 to scroll to the specified area
  $('html, body').animate({
    scrollTop: $("#section").offset().top
  }, 800, function(){
   // Add hash (#) to URL when done scrolling (default click behavior)
    window.location.hash = "";
  });
} // End if  }); });
Utkarsh
  • 1
  • 1
  • 3
0

One possible workaround is to use a <button> instead of a <a>.

So rather than....

<a href="#about">About</a>
<div id="about">Content of this..</div>

...you can change it to

<button href="#about">About</button>
<div id="about">Content of this..</div>

This way the anchor link will not affect the URL.

Stefan
  • 93
  • 2
  • 14
0

For me, only inserting "return false;" solved this issue.

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>   
<script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js" async></script>
<script>
jQuery(document).ready(function($) {
    $('a[href^=#]:not(a[href=#])').click(function() {
        $('html, body').animate({scrollTop: $(this.hash).offset().top}, 1300, 'easeInOutExpo');
        return false;
    });
});
</script>

(This applies to all anchor links on the page.)

Bandi
  • 21
  • 3
  • If you're receiving 'unrecognized expression', put "" arround #, see [Syntax error, unrecognized expression for href](https://stackoverflow.com/a/31197472/4335480) – jamacoe Oct 24 '22 at 15:43
  • `return false` is the bad old way of doing `event.preventDefault()` and should not be recommended in 2022. [`preventDefault`](https://developer.mozilla.org/docs/Web/API/Event/preventDefault) has been around since at least 2003. – Stephen P Oct 24 '22 at 16:22
0

I tried to monitor window.location.hash using a MutationObserver, but that doesn't work, see How to use (or is it possible) MutationObserver to monitor window.location.pathname change?

So now I'm using the window.onpopstate() eventListener:

var flag_onpopstate=false; // use this global flag to prevent recursion
window.onpopstate = () => {
    if (flag_onpopstate) return;
    flag_onpopstate = true;
        window.location.hash = "";
    flag_onpopstate = false;
}

A popstate event is dispatched to the window each time the active history entry changes between two history entries for the same document.

jamacoe
  • 519
  • 4
  • 16
0

The best option is using scrollIntoView.
https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollIntoView

Add a click event to the element you want to be the tag and then handle the click like so:

const handleClickScroll = () => {
    const element = document.getElementById('section-1');
    if (element) {
      //  Will scroll smoothly to the top of the next section
      element.scrollIntoView({ behavior: 'smooth' });
    }
  };

This article solved my problem and is incredibly simple to implement.

https://codefrontend.com/scroll-to-element-in-react/#:~:text=The%20simplest%20way%20to%20scroll,it%20from%20the%20DOM%20directly.