Keep URL unaffected when anchor link is clicked
Asked Answered
P

8

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.

Protoplast answered 9/6, 2013 at 18:4 Comment(2)
You will need to use JavaScript to prevent the default behavior.Madlin
@Madlin Could you be more specific please? I'm not sure how to implement that.Protoplast
L
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>
Leicester answered 9/11, 2014 at 18:44 Comment(1)
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.]Wayfaring
T
2

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.

Tadio answered 9/6, 2013 at 18:15 Comment(0)
B
1
window.location.hash = ""  

is the possible way I could find.

hash gives the string next to #.

Banneret answered 8/3, 2016 at 10:23 Comment(7)
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?Merchandising
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. 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.Banneret
@Merchandising Could you please explain the rationale for downvote?Banneret
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.Merchandising
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.Banneret
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 <a href="#about">? Or did I misunderstand your answer and you ARE using href="#about" and AFTERWARDS you do window.location.hash = "" to clear the URL?Merchandising
Yes, first it scrolls the page to internal link and then you set window.location.hash = "".Banneret
F
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  }); });
Foretoken answered 3/7, 2017 at 12:30 Comment(0)
C
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.

Cicelycicenia answered 12/6, 2019 at 21:57 Comment(0)
C
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.)

Carbonate answered 27/1, 2022 at 18:3 Comment(2)
If you're receiving 'unrecognized expression', put "" arround #, see Syntax error, unrecognized expression for hrefRainwater
return false is the bad old way of doing event.preventDefault() and should not be recommended in 2022. preventDefault has been around since at least 2003.Apian
R
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.

Rainwater answered 24/10, 2022 at 15:58 Comment(0)
S
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.

Selffulfillment answered 19/3, 2023 at 12:19 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.