Grizzly
Grizzly

Reputation: 5953

Anchor element onClick makes page jump to top of page

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.

Upvotes: 22

Views: 75270

Answers (6)

Quangdao Nguyen
Quangdao Nguyen

Reputation: 1373

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.

Upvotes: 7

Wiredo
Wiredo

Reputation: 220

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.

Upvotes: 1

Alexis
Alexis

Reputation: 5831

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.

Upvotes: 0

getjackx
getjackx

Reputation: 345

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.

Upvotes: 1

Amit Kumar
Amit Kumar

Reputation: 5962

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.

Upvotes: 0

Jones Joseph
Jones Joseph

Reputation: 4948

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>

Upvotes: 36

Related Questions