Reputation: 1421
I am trying to do scrollTop animation to an anchor that resides inside of a fullscreen <section>
, but does not scroll to right anchor at first click. Here's my code.
<nav id="scroller"> <a href="#subBox1">Scroll me to sub 1</a>
<a href="#subBox2">Scroll me to sub 2</a>
<a href="#subBox3">Scroll me to sub 3</a>
</nav>
<section id="boxTop"></section>
<section id="boxMaster">
<section id="subBox1">
<p>Hello. I am the Sub 1!</p>
</section>
<section id="subBox2">
<p>Hello. I am the Sub 2!</p>
</section>
<section id="subBox3">
<p>Hello. I am the Sub 3!</p>
</section>
</section>
$("#scroller a").click(function () {
$('#boxMaster').animate({
scrollTop: $(this.hash).offset().top
}, 700);
$("#scroller a").removeClass("active");
$(this).addClass("active");
});
$("#scroller a").click(function() {
$('#boxMaster').animate({
scrollTop: $(this.hash).offset().top
}, 700);
$("#scroller a").removeClass("active");
$(this).addClass("active");
});
html,
body {
margin: 0;
padding: 0;
width: 100%;
height: 100%;
overflow: hidden;
}
#scroller {
position: fixed;
top: 0;
height: 30px;
text-align: center;
}
#scroller a {
color: #fff;
margin: 0 20px;
text-decoration: none;
}
#scroller a.active {
font-weight: bold;
text-decoration: underline;
}
#boxTop {
width: 100%;
height: 100%;
background: red;
}
#boxMaster {
width: 100%;
height: 100%;
background: blue;
overflow: hidden;
}
#boxMaster #subBox1,
#boxMaster #subBox2,
#boxMaster #subBox3 {
width: 100%;
height: 100%;
display: table;
}
p {
color: #fff;
text-align: center;
display: table-cell;
vertical-align: middle;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<nav id="scroller"> <a href="#subBox1">Scroll me to sub 1</a>
<a href="#subBox2">Scroll me to sub 2</a>
<a href="#subBox3">Scroll me to sub 3</a>
</nav>
<section id="boxTop"></section>
<section id="boxMaster">
<section id="subBox1">
<p>Hello. I am the Sub 1!</p>
</section>
<section id="subBox2">
<p>Hello. I am the Sub 2!</p>
</section>
<section id="subBox3">
<p>Hello. I am the Sub 3!</p>
</section>
</section>
Upvotes: 1
Views: 1221
Reputation: 31
I have a fixed header. I started with w3school's code. However, I've been struggling with this same problem for so long, finally found a workaround for the "first click incorrect" issue:
Just before (outside) of my click event, I simply created a variable "x", initialized:
var x=1;
Then I have a conditional statement inside the click event checking for x:
if (x==1) {
console.log("x is now: " + x);
x=0;
console.log("x is now: " + x);
jQuery("html, body").animate({
scrollTop: jQuery("div.class-of-element-i-am-scrolling-to" + hash).position().top - jQuery("div.header-container").outerHeight(true) - jQuery("h3.another-element-in-my-way").outerHeight(true)
}, 2000, function(){
return false;
});
} else {
jQuery("html, body").animate({
scrollTop: jQuery("div.class-of-element-i-am-scrolling-to" + hash).position().top
}, 2000, function(){
return false;
});
}
In other words, using "x" as a flag to check if it is the first time the code is run.
If it is, then I am kind of cheating by subtracting the fixed header and the other elements that are pulling my desired div up. Remember to make "x=0" to "drop" the flag.
If it isn't, then it works fine anyway.
Upvotes: 0
Reputation: 240948
You need to scroll the #boxMaster
element relative to the link's position within the element and relative to the #boxMaster
element's top
position within the body
element.
You can do this by adding the #boxMaster
element's scrollTop()
value with its top
position, and then subtracting that from the link's offset top
value:
$(this.hash).offset().top - $('#boxMaster').position().top + $('#boxMaster').scrollTop()
var $boxMaster = $('#boxMaster');
$boxMaster.animate({
scrollTop: $(this.hash).offset().top - $boxMaster.position().top + $boxMaster.scrollTop()
}, 700);
You may also need to prevent the link element's default behavior using e.preventDefault()
, and then manually scroll the html
/body
element to the #boxMaster
element:
$('html, body').animate({
scrollTop: $boxMaster.offset().top
}, 700);
Upvotes: 1
Reputation: 1711
Add the current scroller value to the offset().top()
, the latter beeing relative to the top of frame, and get rid of this.hash
. Use this.href
instead.
$("#scroller a").click(function () {
var y=$('#boxMaster').scrollTop()
$('#boxMaster').animate({
scrollTop: $(this.href).offset().top + y
}, 100);
});
Upvotes: 3