22

I have a few buttons on my page and onclick they show or hide a few <div> elements.

The <div> elements are positioned towards the bottom of the page so scrolling to those <div> elements is necessary.

Whenever I click on a button, the page jumps to the top. So how do I create an anchor so that when the user clicks the button it will stay on that section of the page?

Here is one of the buttons:

<p class="text-center"><a id="Button-1" class="btn btn-default" href="#" role="button">View Details</a></p>

Here is the <div> that appears when the button above is clicked:

<div class="row">
    <div id="Section-1" class="col-md-10">
        <p>The section to appear.</p>
    </div>
</div>

Here is the JavaScript:

$("#Button-1").click(function () {
    $("#Section-2").hide();
    $("#Section-3").hide();
    $("#Section-1").toggle("show");
    $("#Button-1").text(function(i, text) {
        return text === "View Details" ? "Hide Details" : "View Details";
    });
    return false;
});

Here is my research:

Article 1

Any help would be appreciated.

UPDATE

<p class="text-center"><a id="Button-1" class="btn btn-default" href="javascript:void();" role="button">View Details</a></p>

When I click the button.. I scroll down to see the div that appeared.. then click on another button (that look the exact same as above) and the page returns to the top.

Harry Theo
  • 784
  • 1
  • 8
  • 28
Grizzly
  • 5,873
  • 8
  • 56
  • 109
  • Possible duplicate of [How do I stop a web page from scrolling to the top when a link is clicked that triggers JavaScript?](https://stackoverflow.com/questions/1601933/how-do-i-stop-a-web-page-from-scrolling-to-the-top-when-a-link-is-clicked-that-t) – João Pimentel Ferreira Jun 18 '18 at 19:30

6 Answers6

36

Firstly mention the element correctly in the title. Its a a not button.

Next: The # in your a tag will by default take you to the top of the page when you click on it.

Use a javascript:void() in the href attribute to overcome this.

Like <a href='javascript:void();'>something</a>

Example snippet

<div>

  Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>

  <a href='javascript:void();'>this</a>
</div>
Jones Joseph
  • 4,703
  • 3
  • 22
  • 40
7

This is because an href starting in "#" jumps to the element of that id. For example, href="#mydiv" jump to the element with an id of "mydiv" (nothing happens if that element doesn't exist, so this could be a solution). In the case where no id is provided (ie. Your case; href="#"), it jumps to the top of the page. My go-to solution is adding a preventDefault to the click handler, which "negates" existing behaviors. It can be done like so:

$('.button').click(function() {
 $('#lastclicked').text(this.textContent);
});

$('.button-x').click(function(e) { // Passes the event to the function to allow the prevent default function.
 e.preventDefault();
 $('#lastclicked').text(this.textContent);
});

// Click each of the buttons and notice how the first two jumps to either the div of the top, but the third button ("button-x") doesn't move anything.
body {
    height: 5000px;
    padding: 50px;
}

.buttons {
    position: fixed;
    bottom: 0;
}

.button, .button-x {
    display: inline-block;
    padding: 20px;
    background: #fff;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="buttons">
    <a href="#" class="button">Link with href="#"</a>
    <a href="#mydiv" class="button">Link with href="#mydiv"</a>
    <a href="#" class="button-x">Link with href="#", but a preventDefault.</a>
</div>
<div id="mydiv">
    Last clicked: <span id="lastclicked"></span>
</div>

The important part is the e.preventDefault(), which is the function that blocks the initial behavior of the anchor tag. All you have to do is put that somewhere in your click handler. Make sure to pass "e" as a parameter.

Quangdao Nguyen
  • 1,343
  • 11
  • 25
  • e.preventDefault(); worked for me and is scalable for all buttons! Thanks for the response. Not sure what repercussions there are from "preventing all defaults" but it gets the job done for now! – embulldogs99 Jan 18 '20 at 06:51
1

General fix

Don't use <a>-Tags for your buttons. Convert the <a>-Tags to <button>-Tags or something else (span, p, etc.)

Explanation

That is pretty simple. Your <a>-Tags (namely the buttons) link to '#' which is the so called fragment part of an URI.

Usually fragments are HTML tags which are identified by a name (pre-HTML5)

<a name="top">This is the top section</a>
<a href="#top">Jump to top</a>

or an id (HTML5)

<div id="my-section">Coming soon</div>
<a href="#my-section">Jump to my-section</a>

Because you didn't specify the fragment or didn't use correct one the browser will scroll to the top of the page.

getjackx
  • 345
  • 1
  • 10
1

Have you tried this solution from http://stackoverflow.com/questions/11815295/javascript-inline-onclick-goto-local-anchor

You can use this function on your anchor:

function goToAnchor(anchor) {
  var loc = document.location.toString().split('#')[0];
  document.location = loc + '#' + anchor;
  return false;
}

Usage:

<a href="#anchor" onclick="goToAnchor('anchor')">Anchor</a>

Note that the anchor needs to be enclosed in quotes, without the hash prefix.

Wiredo
  • 220
  • 3
  • 14
0

update href property of a tag to javascript:void();

<p class="text-center"><a id="Button-1" class="btn btn-default" href="javascript:void();" role="button">View Details</a></p>

Demo

javascript:void(); It'll not let link to navigate anywhere.

Amit Kumar
  • 5,888
  • 11
  • 47
  • 85
  • 2
    Still jumps to top of page – Grizzly Apr 25 '17 at 12:53
  • Could the problem possibly be because when the div is toggled to hide.. then the page fits everything.. i mean the page literally extends because of the divs that are being toggled to show – Grizzly Apr 25 '17 at 13:09
0

I suggest you a different approach more generic. Easiest to use and maintain.

Use only one class for each button to detect the click. And store in data property the element that you want to show.

$(".btn-section").click(function(){
  var classToShow = $(this).data("class-show");
  $(".section").hide();
  $("." + classToShow).show();
});
.section{
display:none;
}

.content{
width:100%;
height:2000px;
background-color:#ccc;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="content">Lot of content</div>
<button class="btn-section" data-class-show="section1">Section 1</button>
<button class="btn-section" data-class-show="section2">Section 1</button>
<button class="btn-section" data-class-show="section3">Section 1</button>

<div class="section section1">Section 1</div>
<div class="section section2">Section 2</div>
<div class="section section3">Section 3</div>

This resolve your problem too.

Alexis
  • 5,681
  • 1
  • 27
  • 44