Javascript animate() scrolling does not work as intended - javascript

When I use the code below, it gets very glitchy.
After the animation is complete, I scroll and the page (document) bounces around.
$(document).ready(function (){
$(' .nav, .learn-more').click(function(event){
$('html, body').animate({
scrollTop: $("#"+event.target.id+".featurette").offset().top
}, 1000);
});
});
Please see the demo on Codecademy.

The bouncing happens when the animation didn't finish yet and the script would keep the page scrolling, then you try to counter-scroll, and due to the way jQuery animations work, your counter-scrolling gets reset by the continuation of the scrolling animation.
Upon looking at your linked example, I found out why your animation was jumpy. The selector you use for attaching the click handler is $(' .nav, .learn-more'), and in your HTML, there's 2 .navs, one being the child of the other:
<div class="nav">
<div class="container">
<ul class="pull-leftnavnav-pills">
<li><a id="" href="#">Home</a></li>
Because of this, the animation is called twice, causing the flickering. You should modify your selector to $('.nav .nav, .learn-more'), or use something more unique like $('.nav.nav-pills, .learn-more').
$('.nav .nav, .learn-more').click(function(event){
$('html, body').animate({
scrollTop: $("#"+event.target.id+".featurette").offset().top
}, 2000);
});
Here's the fixed code in the code sharing platform of your choice: http://www.codecademy.com/DJDavid98/codebits/GSoDQf

Related

smooth scroll does not work with overflow-y

I am trying to use a smooth scroll and adopted an example I found online. Here is a fiddle with my code
https://jsfiddle.net/4DcNH/144/
I have special conditions set to html and body (basically to offset the page context by 50px from the top to avoid the navbar). Therefore the smooth scroll does not work. Does anybody know a solution to this?
thanks
carl
$(document).ready(function() {
$('a[rel="relativeanchor"]').click(function(){
$('html, body').animate({
scrollTop: $( $.attr(this, 'href') ).offset().top
}, 2000);
return false;
});
});
Is this what you're after?
$(document).ready(function () {
if(!/chrom(e|ium)/.test(navigator.userAgent.toLowerCase())){
$('html').css({'overflow-x':'auto','overflow-y':'hidden'});
}
$('a[rel="relativeanchor"]').click(function () {
var $el = $($(this).attr('href'));
$('html, body').stop().animate({
scrollTop: $el.prop('offsetTop')
}, 2000);
return false;
});
});
JSFiddle
Updates were needed in the CSS. The html overflows were removed for chrome, because otherwise, this would not work in Chrome. However, the overflows are needed for Firefox, so they are done by setting it dynamically in the JavaScript (set if not chrome).
If you want to maintain an offset, subtract it from the calculated offset. Given the above, $el.prop('offsetTop') - 50 adds 50px above.
The issue appears to be related to differences in how Chrome scrolls the <body> with height:100%. A discussion of the issue is here: Body set to overflow-y:hidden but page is still scrollable in Chrome
A workable solution is to wrap the scrolling content in <div class="content"> and disable scrolling on <body>.
Here's a JSFiddle to demonstrate the updated behavior: https://jsfiddle.net/f1zv1c5k/5/
To get the scroll to stop at the appropriate point, you need to subtract the vertical offset applied to the <html> tag (using $el.prop('offsetTop') recommended by #vol7ron) when scrolling. Your smooth scroll function would look like this:
$('a[rel="relativeanchor"]').click(function(){
var $el = $($(this).attr('href'));
$('.content').animate({
scrollTop: $el.prop('offsetTop')
}, 2000);
return false;
});

Click-triggered scrollTop takes random amount of time to fire

I have a comment section which automatically scrolls into view when you scroll it (using jQuery scrollTop), and then a button which scrolls you back up when you click it. The first scrolling action always runs perfectly, but the second scrolling action takes a seemingly random amount of time to occur after the button is pressed.
A live demonstration can be found here: www.rouvou.com/KanyeWest. Go down to the comment section, and scroll it to fire the first jquery scroll. Then click the "Back" button to fire the second scroll. It might work instantly the first few times you try it, but if you do it enough, it should be delayed eventually.
html
<div id="comment-section">
<div id="comment-background-up">BACK</div>
<div id="good_comments"><!--CONTENT--></div>
<div id="bad_comments"><!--CONTENT--></div>
</div>
jquery
$("#good_comments").scroll(function() {
$('html, body').animate({
scrollTop: $("#good_comments").offset().top
}, 700);
$("#comment-background-up").fadeIn(200);
});
$("#bad_comments").scroll(function() {
$('html, body').animate({
scrollTop: $("#bad_comments").offset().top
}, 700);
$("#comment-background-up").fadeIn(200);
});
$("#comment-background-up").click(function() {
$('html, body').animate({
scrollTop: $("#randomajax").offset().top
}, 700);
$(this).fadeOut(200);
});
Does anyone know what could be causing this delay?
I suppose this is happening because jQuery daisy-chains the animations. And you initiate the animation on every scroll. So the much you scroll, the more 700ms animations "pile up", hence your go back animation waiting for them all to finish.
It would probably be best to update your code to avoid chained scrollTop animations on the body.
However, for now you could fix this by using jQuery's stop function. I.e.:
$("#comment-background-up").click(function() {
$('html, body').stop(true, true).animate({
scrollTop: $("#randomajax").offset().top
}, 700);
$(this).fadeOut(200);
});

re stylign anchor tag to remove jerky scroll

I have a html page with a form and a anchor tag at the end of the page that scroll when clicked scrolls back to the top of the page with a smooth scroll implemented using javascript.
The problem I am facing is that the scroll is jerky. There is a slight jerk before it proceeds to scroll. This doesn't happen in jsfiddle though.
I am not sure if it is because of the anchor tag or JS. Is there a way I can fix it by changing/styling anchor tag to regular text. I believe the problem is something to do with the anchor tag. I am not sure though.
Thanks
alert("Scroll triggered");
$('a[href="#register"]').click(function(){
$('html,body').animate({scrollTop: '0'}, 1000);
$('input#Name_First').focus();
});
JSFiddle: http://jsfiddle.net/BrianDillingham/co1ot6ru/7/
Your JS fiddle uses the code
$("html, body").animate({ scrollTop: "0px" }, 1000, function(){
$('input#Name_First').focus();
});
If you change it to the code provided in the question
$("html, body").animate({ scrollTop: "0px" }, 1000);
$('input#Name_First').focus();
It also jerks;
This shows that the issue is - the "focus" needs to be in the callback for the animation.

Efficient way of scrolling to part of page with jQuery links

I've asked for help in regards to a scroll identifier and now have this code working perfectly:
http://codepen.io/vsync/pen/Kgcoa
However, I was wondering how I can get it so when I click the links on the black scrollbar I can get it to scroll to that part of the page. I think it would be something along these lines:
$(".a1").click(function() {
$('html, body').animate({
scrollTop: $("#a1").offset().top
}, 2000);
});
The scroll identification bit of the JavaScript has been so refined that I was really hoping there would be an elegant and optimised way to make it so they can skip to bits of the page too.
Try this.
$("nav span").click(function() {
var sectionId = $(this).attr('class')
$('html, body').animate({
scrollTop: $('#'+sectionId).offset().top
}, 2000);
});
Fiddle Demo

Using .offset().top with .slideUp

I'm trying to make the window scroll to an element on click. It is working, except when the slideUp animation of one of the previous elements fires, the clicked element scrolls up way past the top.
Here's the link: http://jtwebfolio.com/mobi
NOTE: Size your browser down to mobile width to best see the issue. Also, this is taking place on the portfolio projects.
Here's the code:
$('article.project header').click(function(){
if($(this).parent().hasClass('clicked')){
// If the clicked project has already been clicked, remove the class and hide the content
$(this).parent().removeClass('clicked');
$(this).parent().find('.proj_content').slideUp('fast');
}else{
// Remove the class and slide the content up on all projects
$('article.project').removeClass('clicked');
$('article.project .proj_content').slideUp('fast');
// Add the class and show the content on the selected project
$(this).parent().addClass('clicked');
$(this).parent().find('.proj_content').slideDown('fast');
// Slide the project to the top after clicking on it
$('html, body').delay(500).animate({
scrollTop: $(this).parent().offset().top
}, 500);
}
});
If someone could help me produce the desired effect, that would be amazing. Thanks in advance!
A couple of things:
Your .slideDown()s use the speed fast, but you're only delaying by 500ms. fast is synonymous with 600ms. In general, I think it's a bad idea to use both as it's very confusing to someone reading your code what fast is.
Rather than using .delay() method, I'd use the complete argument on the slideDown or slideUps, so that once they're complete, you do your scrolling. This makes more sense, as you'd then not have to worry about conflicting timings.
My guess would be that your problem is caused by your transitions taking 600ms, but your scroll only waiting 500ms. At 500ms, it's getting the wrong offset values and scrolling to those.
Perhaps you should consider changing your markup to something like:
$(this).parent().find('.proj_content').slideDown('600', function() {
// Slide the project to the top after clicking on it
$('html, body').animate({
scrollTop: $(this).parent().offset().top
}, 500);
});
* Note: I've changed fast to 600 for clarity's sake.
try this :
$('article.project').on('click','header',function(){
_parent = $(this).parent();
if(_parent.hasClass('clicked')){
// If the clicked project has already been clicked, remove the class and hide the content
_parent.removeClass('clicked');
.find('.proj_content')
.slideUp('fast');
}else{
// Remove the class and slide the content up on all projects
$('article.project').removeClass('clicked')
.children('.proj_content')
.slideUp('fast');
// Add the class and show the content on the selected project
// Slide the project to the top after clicking on it
_parent.addClass('clicked')
.find('.proj_content')
.slideDown('fast',function(){
// callback
$('html, body').animate({ scrollTop: +(_parent.offset().top)+'px' }, 500);
});
}
});

Categories

Resources