How to prevent jump on an anchor click?
Asked Answered
U

9

14

I use e.preventDefault(); to disable default anchor behaviour.

Is there a way to prevent only jump action to a target on click?

I tried:

  var hash = window.location.hash;
  var link = $('a');
  $('a').click(function() {
    e.preventDefault();
    hash = "#"+link.attr("href");
  });

But it doesn't work: http://jsfiddle.net/ynts/LgcmB/.

Uzzia answered 6/1, 2013 at 19:41 Comment(0)
W
28
$(document).ready(function() {
  var hash = window.location.hash;
  var link = $('a');
  $('a').click(function(e) {
    e.preventDefault();
    hash = link.attr("href");
    window.location = hash;
  });
});

You also have to specify event argument in the function. By naming it as e or event and then you can manipulate it.

Wheeze answered 6/1, 2013 at 19:42 Comment(16)
Was just about to comment on the lack of explanation for the missing event, but there it was, +1.Lowboy
heheheh :P I will never miss descriptions in my answers :DWheeze
Unfortunately, there is no jump action and no url update. I want to have jsfiddle.net/ynts/Jgkmt/embedded/result/#anchor after click.Uzzia
edited my answer :D It may not work in the jsFiddle because they use iframes!Wheeze
Once window.location is set, a jump to #anchor happens :(.Uzzia
can you explain a little more?Wheeze
@AspiringAqib I put this example from jsFiddle to test_1.html. The link is clicked → url in adress bar is added with #anchor (on window.location = hash;) → jump to p#anchor happens. So all steps of default click action on an anchor link are here. My idea was to get only #anchor added to page adress in adress bar and no page scroll to p#anchor.Uzzia
well you can use, this plugin: benalman.com/projects/jquery-hashchange-plugin and add this code to jQuery: $(window).hashchange( function(e) { e.preventDefault(); }); I think it will work and if worked then don't forget to do something ;)Wheeze
@AspiringAqib still no luck: test_2.html.Uzzia
let us continue this discussion in chatWheeze
<script> $(document).ready(function() { var hash = window.location.hash; var link = $('a'); $('a').click(function(e) { e.preventDefault(); hash = link.attr("href"); window.location = hash; }); }); $(window).hashchange( function(e) { e.preventDefault(); }); </script> You were adding that function in other event which occurs on click!Wheeze
@AspiringAqib I tried this variant, too. It doesn't resolve the issue.Uzzia
oh buddy then I have also never tried these things but can you explain why you wanna stop it to do that?Wheeze
@AspiringAqib I use a script for tabs that works with anchors. It works smooth. But I want to add #href-value to a page adress in adress bar when a tab is clicked. However, once URL is updated, a page jumps to div#href-value. So I lose "smoothness" of tabs behavior.Uzzia
window.location.hash = hash is more safe than window.location = hash isn't it?Kierkegaard
Seems like an obtrusive script behavior to intercept the click event and prevent it, then fish the href value out of the attribute and assign it the to the window location. Perhaps a better way: https://mcmap.net/q/790862/-how-to-prevent-jump-on-an-anchor-clickIchabod
I
16

This is the only solution I could come up with that works consistently across all desktop and mobile browsers or webviews with various client UI libraries and frameworks. By getting the window coordinates before scrolling occurs we can revert and maintain the current scroll position.

$('a').click(function (e) {
    var x = window.pageXOffset,
        y = window.pageYOffset;
    $(window).one('scroll', function () {
        window.scrollTo(x, y);
    })
});
Ichabod answered 31/12, 2015 at 9:18 Comment(4)
I tried different solutions but your solution is very good. it worked on searching alsoSarco
This had same affect for me as just using e.preventDefault();Octameter
This will not cause wierd behavior within a WKWebView!Bethlehem
@Octameter and @Bethlehem that's the idea : "Is there a way to prevent only jump action to a target on click?" The event default behavior is not prevented via e.preventDefault() nor is e.stopPropagation() occurring. Only the UI jump behavior is prevented via scroll position value revert before painting as asked.Ichabod
J
5

To only prevent the "jump" you have to use different id for the target element than what is specified in the anchor.

e.g. for a link to a new tab use,

<a href="#new" />

and for the target element mask the id

<div id="new-tab"></div>

Then in your script append the mask to the real hash, and use it to get the element.

$(window).on("hashchange", function(){
    var hash = this.location.hash;
    var mytab = $(hash + "-tab");
});

This preserves the hash location changes in browser history that can be controlled by the back/forward buttons, and detected on page load with the hashchange event if user enters the page with hash specified.

Jessi answered 7/8, 2014 at 8:41 Comment(2)
Thanks so much for this comment. I did this long ago and couldn't figure out for the life of me remember what I did to solve the stupid cross-page reload scrolling issues. Your answer reminded me of the good ol' masking method!Alina
Very helpful in different circumstances. E.g. define a boolean on page load, change the anchor, prevent the jump. After page load handle clicks on inner anchors as usual.Fishman
M
3

You should bind an onclick event to anchor and specify return false; as a result. The return false; statement causes default click behaviour (jump) would not work. You can find more info here: How to disable anchor "jump" when loading a page?

Menander answered 30/7, 2013 at 15:4 Comment(1)
In jQuery, it might look like this: $("a[href='#']").on('click', function(event) { return false; });Lantana
C
2

You need to pass the event on the function.

var hash = window.location.hash;
var link = $('a');
//pass event here
$('a').click(function(e) {
    e.preventDefault();
    hash = "#"+link.attr("href");
});
Charmer answered 6/1, 2013 at 19:43 Comment(2)
Yeah, while I was typing I seen another answer had been posted. Good answer Aspiring Aqib.Charmer
well, i can't understand why i get exhausted while answering if i see, somebody else also have answered. "1 new answer to this question. Click to Load". :DWheeze
O
1

After first trying the other answers on this page, this was all I needed:

  $('a').click(function (e) {
    e.preventDefault();
  });
Octameter answered 3/1, 2020 at 3:53 Comment(0)
M
0

You can use match with ^ to detect starting with #

$("a:link").on("click", function(e){
    if($(this).attr("href").match("^#")) {
        e.preventDefault();
        //some other stuff you want to do with the hash, like smooth scroll to anchor
        $('html, body').animate({ scrollTop: $($(this).attr("href")).offset().top }, 'fast');
    }
});
Murcia answered 4/10, 2019 at 9:19 Comment(0)
E
0

On your toggle or whatever when you don't want the scroll to trigger this guy I found has a good solution here that i added to for my use case. https://ben.page/js-remove-hash

here's what i did to remove the hash and prevent the jump (scrollLeft: how far you've scrolled horizontally. scrollTop you can get the gist (vertically))

const removeHashAndPreventJump = () => {
   const { scrollTop, scrollLeft } = document.documentElement;
   window.location.hash = ''; //clear hash
   window.scrollTo(scrollLeft, scrollTop);
}
Eri answered 26/7 at 22:54 Comment(0)
H
-1

Add any string after the hash:

<a href="#anystring">
Hectometer answered 4/11, 2022 at 3:59 Comment(1)
The OP is passing hash = "#"+link.attr("href");Leesen

© 2022 - 2024 — McMap. All rights reserved.