jQuery - Changing width makes the page jump to the top - javascript

I am trying to have this navigation sidebar that slides away some time after the mouse leaves, making the text-part expand. The thing is, that whenever the sliding function starts, the page jumps to the top. There's no "#" used, I tried overflow-y: scroll, return false at the end of the function, preventDefault, but nothing works.
Here's the js code
$(document).ready(function(){
$("#navbar").delay(5000).animate({left: "-=15%"});
$("#navwrap").css("width","2%").css("position","fixed");
$("#bodywrap").delay(5000).animate({width: "90%"});
$("#navbar").mouseleave(function(){
$(this).stop(true, true).delay(3000).animate({left: "-=15%"});
$("#bodywrap").delay(3000).animate({width: "90%"});
$("#navwrap").css("width","2%").css("position","fixed");
});
$("#navwrap").mouseenter(function(){
$("#navbar").stop(true,false);
$("#bodywrap").stop(true,false);
if ($("#navbar").css("left") != "0%"){
$("#navbar").animate({left: "0%"});
$(this).css("width","15%").css("position","initial");
$("#bodywrap").animate({width: "75%"});
};
});
});
And here's the fiddle: http://jsfiddle.net/uuw2dzry/1/

Much of the animations and delays can be done by CSS
http://jsfiddle.net/fkL57v9d/
Your code is overly complicated and leaves room for bugs and undesired results. I'd consider re-creating this page in a simpler way.

Related

JavaScript scroll based animation is choppy on mobile

I have 2 divs (left and right) and i want to scroll the left based on the right.
https://jsfiddle.net/3jdsazhg/2/
This works fine on desktop, but when i change to mobile, it's not smooth anymore...
This can be noticed very easily, by changing
_left.style.top = _content.scrollTop - (_content.scrollTop * ratioLeftRight) + 'px';
to
_left.style.top = _content.scrollTop + 'px';
Where it should act as a fixed positioned div
I would like to know the exact reason why this isn't smooth... I know that it's not the animation. Simple animation on the div is smooth, the issue comes up when it's based on scroll.
How can i make this animation smooth?
It's probably choppy because it's being fired ALOT when being scrolled, in fact i'm pretty sure IOS mobile pauses the javascript execution whilst the user is scrolling.
Instead I'd suggest using an interval, you could tweak the time between each interval to what feels good for your use-case.
Although it may seem intensive that it's firing this logic every X millisecond when using the scroll event you could be firing the event off hundreds of times per second, which is going to be far more intensive and noticeable to a user using a device with limit processing power.
(function () {
var interval = null,
//Currently set at 0.4 seconds, play with the code
//and change this value to see what works best for
//this use-case
time_between_interval = 400;
setInterval(scrollLogic, time_between_interval);
function scrollLogic () {
//The function body of what you're assigning
//to the scroll event.
}
//I have omitted clearing the interval but you would want to do that, perhaps on page change, or something.
//clearInterval(interval);
})();
I finally managed to think out a solution.
From my point of view, i'm guessing the mobile view fires the scroll event less often and because we are scrolling the wrapper, we first scroll the whole page and then scroll back with js the left part and because it's different from the desktop version, this issue becomes visible...
The solution was to change the left side to fixed position, and substract from the top instead of adding to it.
_left.style.top = -(_content.scrollTop * ratioLeftRight) + 'px';

Javascript focusing a large div with fixed header

I'm using a tiny library called '$.scrollTo' to animate a scroll to a div element in my html. at the top of my page I have a fixed navgation bar.
at the end of the animation, I would like to have that div focused (for accessibility). if my div is to large, at the end of the animation, the fact that it gets focus - simply sends it a bit off the screen.
This does not happen with small divs.
here is my code (check jsfiddle below):
$('#buttonid').on("click", function() {
//fixed nav bar height (to compensate when scrolling)
var fixed_navbar_height = $("#navbar-id").height();
//the element to scroll to
var $go_to_selector = $("#topic2");
$.scrollTo($go_to_selector, {
duration: 1000,
offset: -fixed_navbar_height,
onAfter: function() {
//if you comment out this .focus it works as intended.
$go_to_selector.focus();
}
});
});
here is a JSFIDDLE example:
https://jsfiddle.net/dy35obpq/3/
obviously the onAfter messes it up, but i would like both the animation and the focus. Any ideas on how to implement a focus on a large div without letting it change the scroll bar ? suggestions are more than welcome.
Try this.
onAfter: function() {
$go_to_selector.focus();
$(window).scrollTop($($go_to_selector).offset().top - fixed_navbar_height);
}
I have simply added this line in your onAfter callback.
$(window).scrollTop($($go_to_selector).offset().top - fixed_navbar_height);
and it seems to have fixed the problem while still retaining focus. You might want to use css to disable the focus blue highlight.

Why does my page jump around so much?

I'm very confused with my current webpage: http://armandbakx.nl/ - (adjusted it, I'm not here for self-promotion).
The idea is that I have a couple of images on my page, which are clickable. Once clicked a scrollable container should pop up, showing more information and images.
So far, with the help of some great people here, I've managed to make the JavaScript work. The only problems I'm running into right now are that when I click an image, the entire 'back-page' shifts. I'm not sure what's causing this, and even more unsure how to solve it.
Secondly, when an image is clicked and the scrollable container 'hovers' over the main page, it seems that other images still respond to clicking.. I've already hammered the z-index up to ridiculous amounts but it still does this. I don't think this is a JavaScript issue, but can't fathom what causes this in the css.
Thirdly, when an .img is clicked, and you scroll through the content of the scrollable container, when you click back towards the main page, it often also ends up scrolled upwards or downwards. How do I prevent this from happening?
I hope it's somewhat comprehensible and I hope someone is willing to help me.
I have a codepen here with everything this page runs on at the moment, except for the images.
Codepen
$('img').on('click', show);
$('.overlay').on('click', hide);
function show(){
$('.scroll-container').eq($(this).parent().index()).addClass('show');
$('.content-container').addClass('no-scroll');
$('.overlay').addClass('opacity');
}
function hide() {
$('.scroll-container').removeClass('show');
$('.content-container').removeClass('no-scroll');
$('.overlay').removeClass('opacity');
}
I decided to just answer your third question, and this approach might prevent the other issues as well.
Inside of your show function, make the keep track of the position the browser was in when the content opened. Then, in your hide function, return the browser to that position. This should prevent your boxes from moving around.
Here is an example. I wrapped everything in an immediately-invoked function to prevent the variables from being globals.
(function(){
var currentTop = 0;
$('img').on('click', show);
$('.overlay').on('click', hide);
function show(){
currentTop = $(window).scrollTop();
$('.scroll-container').eq($(this).parent().index()).addClass('show');
$('.content-container').addClass('no-scroll');
$('.overlay').addClass('opacity');
}
function hide() {
$(window).scrollTop(currentTop);
$('.scroll-container').removeClass('show');
$('.content-container').removeClass('no-scroll');
$('.overlay').removeClass('opacity');
}
})();

Make sure only one animation is being fired

I am running this animation on $(window).scroll() and it works fine for the most part.
$('#el').animate({ left: toMove }, 500);
The problem is if the user scrolls too fast, two animations will fire and the second animation will fire before the first one has moved far enough. How can I make sure there is only one animation at any given time and then the other animations will follow? I need the element to animate left FULLY any other animations run but I need them all to run. I tried using .queue() but couldn't find the right solution with it.
You could use the stop function like this to smooth things up:
$('#el').stop(true, false).animate({ left: toMove }, 500);
The stop function, when calling like that will clear the animation queue for any waiting animation, as well as stop the current animation if any.
Edit
If you want the animation to end before animating again you just need to call .stop(true, true) instead

animate() not updating fast enough

I'm making a navigation bar that remains at the top of the page. When the user scrolls down, this bar will shrink, and when the user goes back to the top of the page, the navbar returns to its original dimensions.
Problem: When the user scroll down, the navbar shrinks as expected. However if the user scrolls back to the top of the page quickly, the navbar remains shrunken, and the animate() function within the scrollTop() callback function triggers after a few seconds.
To debug this, I included console.log($(window).scrollTop()); to tell me the current position of the user on the page. I get the console.log output as quick as the user scrolls. But {console.log('animated'); which is supposed to fire when the animation is completed, does not appear till a few seconds later after console.log($(window).scrollTop()); outputs 0.
How can I get animate() to respond quickly when the user scrolls up?
JS Code
var navBar = $('#navbar-inner');
var top = navBar.css('top');
$(window).scroll(function() {
console.log($(window).scrollTop());
if($(this).scrollTop() > 50) {
navBar.animate({'marginTop':'-20', 'height':'60'}, 300);
} else {
navBar.animate({'marginTop':'0', 'height':'80'}, 300, function()
{console.log('animated');});
}
});
(Posting my comment as an answer)
Use .stop() to stop any ongoing animations before starting a new one.
I experienced this kind of issues before with animations that last longer than the user action. You just need to stop the animation, something like
navBar.stop(true, true).animate(...);
To understand stop() better here is the link http://api.jquery.com/stop/. Hope it helps

Categories