jquery animate simultaneous with 'html,body' scrolling/animation - javascript

I'm trying to animate two things at the same time. one is
var submenuHeight = parseInt($("#submenu").height());
console.log(submenuHeight);
var scrollOffset = parseInt($(window).scrollTop());
console.log(scrollOffset);
scrollOffset = scrollOffset - submenuHeight;
console.log(scrollOffset);
$("#submenu").animate({
height: '18px'
}, {
duration: 250,
queue: false
});
$('html, body').animate({
scrollTop: scrollOffset
}, {
duration: 250,
queue: false
});
<div id="submenu"></div>
the side then includes lots of text. I want to be able to close the menu but stay at the same piece of text, meaning animate the scrolling to the same part of the page.
but weirdly this animation does not work simultaneously even though I set queue to false. what might be going wrong?

Related

How to prevent jerkiness on mouseenter/leave

I'm currently trying to develop a list of projects, which on mouseenter/leave triggers a function. Currently on mouse enter the background block slides out of view to the right and on mouse leave the background block slides back into view. This works as expected, but when I enter and leave multiple times, the animations trigger and jerk around - loosing the smooth scroll effect that I'm trying to achieve. How would I go around preventing the jerkiness, I've tried adding a 'disable' class, but this doesn't seem to work. Any and all advice would be helpful.
jQuery V1:
project.mouseenter(function() {
var project = $(this).hasClass('disable');
if(!project){
var colourDuration = 750, colourDelay = 550;
$(this).find('.colour-block').stop(true,false).velocity({left:'100%'},{duration: colourDuration, delay: colourDelay, complete: function() {
$(this).addClass('disable');
}});
$(this).find('p').stop(true,false).velocity({height:'26px'},{duration: 500, delay: 225});
$(this).find('button').stop(true,false).velocity({height:'26px'},{duration: 500, delay: 225});
}
});
project.mouseleave(function() {
var project = $(this).hasClass('disable');
if(!project){
var colourDuration = 750, colourDelay = 550;
$(this).find('.colour-block').stop(true,false).velocity({left:0},{duration: colourDuration, delay: colourDelay, complete: function() {
$(this).removeClass('disable');
}});
$(this).find('p').stop(true,false).velocity({height:0},{duration: 500, delay: 225});
$(this).find('button').stop(true,false).velocity({height:0},{duration: 500, delay: 225});
}
});
jQuery V2:
project.hover(function() {
var colourDuration = 750, colourDelay = 550;
$(this).find('.colour-block').velocity({left:'100%'},{duration: colourDuration, delay: colourDelay});
$(this).find('p').velocity({height:'26px'},{duration: 500, delay: 225});
$(this).find('button').velocity({height:'26px'},{duration: 500, delay: 225});
}, function() {
$(this).find('.colour-block').velocity('stop').velocity('reverse');
$(this).find('p').velocity('stop').velocity('reverse');
$(this).find('button').velocity('stop').velocity('reverse');
});
Velocity JS
http://velocityjs.org/
Screenshot:

Keep element at height after animating

Im trying to increase an elements height when hovering over it but at the moment when you move the mouse away from the element it reverts the height, is there a way to keep the element at the height I animate to? Here's my code so far:
var width = $(window).width();
$("#projects .project:first").addClass("active");
$("#projects .project:first").height(100);
if (width > 800) {
$('#projects .project').hover(function (e) {
e.preventDefault();
var prev = $("#projects .project.active");
$('#projects .project').removeClass('active');
$(this).addClass('active');
if ($(this).find("p").text().trim().length) {
$(this).animate({
height: '100px'
}, { duration: 1000, queue: false });
$(prev).animate({
height: '30px'
}, { duration: 1000, queue: false });
}
});
}
I found in the end the best solution to achieve the functionality I wanted was using accordion: http://jqueryui.com/accordion/

Continuously scroll an element to bottom and back to top of a parent element

I am trying to automatically .animate the .scrollTop of a <div> contained within another <div>. I have done this so I could hide the scroll-bar thus only display the text. Therefore, I know how to scroll that particular <div> with JQuery as such:
$("#div").animate({ scrollTop: "+=5" }, 200);
But what I am trying to do is to continuously .animate the content until it reaches the bottom of that particular <div> and then animates back to the top of the <div> ( .scrollTop: '0px'). THere is where I am struggling with.
I am currently pulling content into a <div> which the result of a
query. Therefore, I do not know the full length of the content that
will be placed of that <div>.
The <div> that contains the content is within another <div> and I don't think the method to detect the bottom of the <div> works correctly (or perhaps I am doing something wrong).
var div = $(this);
if (div[0].scrollHeight - div.scrollTop() == div.height())
I was wondering if someone can give me a hand with this. Since I have not seen a particular approach like this in this forum or by Googleing for it.
So pretty much what I have is this:
if ($('#resultProviders').scrollTop() >= $('#resultProviders').innerHeight()) {
$('#resultProviders').animate({ scrollTop: "0px" }, 800);
} else {
$('#resultProviders').animate({scrollTop: '+=30px'}, 500);
};
I have also provided a Fiddle for this.
https://jsfiddle.net/trinkermedia/ebhydbp3/5/
Many thanks.
I'd use a scroll function with a parameter, like shown in this fiddle.
function _scroll(goDown) {
goDown = goDown == undefined ? true: goDown;
var frame = $('#resultProviders'),
content = $('#resultProviders ul'),
scrollTo;
if (goDown) {
scrollTo = content.outerHeight() - frame.outerHeight();
} else {
scrollTo = 0
}
frame.animate({
scrollTop: scrollTo
}, {
duration: 2000,
complete: function() {_scroll(!goDown)}
});
}
Things are so simple with GSAP, here is your fiddle: jsFiddle.
JavaScript:
TweenMax.to('#resultProviders', 2, { scrollTo: { y: 'max' }, repeat: -1, yoyo: true, ease: Power2.easeInOut });
Apologies if this wasn't you were looking for or if you were not interested in solutions utilising anything else other than jQuery.

Automatically scrolling page

I'm working on an info screen that displays a table of informations which usually is quite long, so I want it to scroll slowly down automatically until it reaches the bottom, fades to white, scroll back up, and fades out from white, repeating the process all over after some delays.
Currently I have this code:
var iInterval = 2000;
var iScrollInterval = 5000;
var iFadeInterval = 500;
var loop = function() {
var iScroll = $(document).height() - $(window).height();
$("html, body").animate({
scrollTop: iScroll
}, {
duration : iScrollInterval,
easing : "linear",
complete : function() {
$("body").fadeOut(iFadeInterval).delay(iFadeInterval);
$("html, body").scrollTop(0);
$("body").fadeIn(iFadeInterval);
}
});
setTimeout(loop, iInterval);
};
setTimeout(loop, iInterval);
The problem with that code is that scrolls down to the bottom, immediately jumps to the top again, without fading and keeps scrolling down immediately without delay.
This behavior is repeating 2-3 times until, finally, the fading to/from white happens, once the bottom of the page is reached for the 3rd time.
There's no doubt I've misunderstood something here, but what?
I haven't been using jQuery for a while, but after looking at your code there is couple of things:
Why are you scrolling both HTML and BODY?
The page jumps back up because you are not animating it here:
$("html, body").scrollTop(0);
And al other problems derive from that. If I have a minute I will update my answer with fiddle
Fiddle:
http://jsfiddle.net/64etqaxc/1/
var iInterval = 2000;
var iScrollInterval = 5000;
var iFadeInterval = 500;
var loop = function() {
var iScroll = $(document).height() - $(window).height();
$("html").animate({
scrollTop: iScroll
}, {
duration : iScrollInterval,
easing : "linear",
complete : function() {
$("body").fadeOut(iFadeInterval, function(){
$("html").scrollTop(0);
$("body").fadeIn(iFadeInterval,function(){
loop();
});
});
}
});
};
loop();

jQuery scrollTop is incorrect by the height of a slideUp div

I have a series of news items (alerts and announcements, to be precise), each individually wrapped inside their own <div> tags, set to hide everything but their headline on page load. On clicking any headline (h2) that individual item's details reveal (slideDown), and any other open items collapse (slideUp). Thus only one news item is viewable at a time. All good.
I also have my code set to scrollTop to the top of the recently clicked div when the window width is tablet sized or less (767px). This only works partially.
I know what the problem is, but not the solution.
The problem is that when I click a different news item, it's scrollTop coordinates are off by the height of the div that's being auto-closed. I've banged my head enough, and the solution's probably simple, but I'm not coming up with it.
The page is live here: http://northqueensviewhomes.com/announcement-test
Remember to make your page width less than 767px and refresh (you'll see the layout respond when you're small enough, then click around a few of the top alert items and you'll eventually see one of them scroll way too high, or even down instead of up to the top of the $this div.
Here's my jQuery:
if ($('#bboards').length) {
/* Page Load Cleanup */
$('.announcement_item h2 + div,.alert_item h2 + div').hide().removeClass('toggler');
$('.moreText').removeClass('hidden');
function hideAll() {
$('.announcement_item h2, .alert_item h2').removeClass('toggler').children('.moreText').fadeIn('fast').end().next('div').slideUp('fast');
}
$('.announcement_item h2,.alert_item h2').hover(function() {
$(this).css({
'cursor': 'pointer',
'color': '#BC2E34',
});
}, function() {
$(this).css({
'cursor': 'default',
'color': 'black',
});
}).click(function() {
if ($('.toggler').length) {
var previouslySelected = $('.toggler').parent('div').height();
alert(previouslySelected);
} else {
var previouslySelected = 0;
// alert(previouslySelected);
}
if ($(this).hasClass('toggler')) {
hideAll();
$('.toggler').removeClass('toggler');
$(this).children('.moreText').fadeIn('fast'); //this is the "click to read more… text on the link"
if ($(window).width() <= 767 {
$('html, body').animate({
scrollTop: ($(this).parent('div.well').offset().top - 13)
}, 2222, 'easeInOutExpo');
}
} else {
hideAll();
$(this).addClass('toggler').next('div').slideDown('fast', 'easeInOutQuad');
$(this).children('.moreText').hide(); //this is the "click to read more… text on the link"
if ($(window).width() <= 767) {
$('html, body').animate({
scrollTop: ($(this).parent('div.well').offset().top - 13)
}, 2222, 'easeInOutExpo');
}
}
});
} // <--- End if $('#bboards').length
and you can see the HTML live on the page. I've added a bunch of dummy entries just to create page height.
I'm pretty sure that I just need to delay the scrollTop until the slideUp is complete, but, again, not sure how.
There are two relatively easy solutions you could try.
The first is, as you said, to delay the scrollTop animation:
setTimeout(function() {
$('html, body').animate({
scrollTop: ($(this).parent('div.well').offset().top - 13)
}, 2222, 'easeInOutExpo');
}, 200);
Or, you can record the initial position of every announcement and alert after you hide their contents when the page loads. Change your section labeled /* Page Load Cleanup */ to the following:
/* Page Load Cleanup */
$('.announcement_item h2 + div,.alert_item h2 + div').hide().removeClass('toggler');
$('.moreText').removeClass('hidden');
$('.announcement_item, .alert_item').each(function() {
$(this).data("top", $(this).offset().top);
});
This gives every announcement a data entry that stores its initial position. Then, whenever you need to animate the scrollTop, do the following:
$('html, body').animate({
scrollTop: ($(this).parent('div.well').data().top - 13)
}, 2222, 'easeInOutExpo');
Note that this will only work well if the contents of the announcements and alerts do not change.
I hope this helps!

Categories

Resources