I've seen something like this in Java and I'm wondering if it's there something similar in JavaScript/jQuery. Basically I have a function with an animation and a code that runs at the end of it:
$('html,body').animate({ scrollTop: 0 }, 'slow', function(){
lastScrollTop = $(this).scrollTop();
});
However, I want this code to be updated during the animation e.g.: if the user is 500px, I want lastScrollTop to become 450,400,300,200,100,50,0
Is there a way to keep my variable updated during the animation?
You should look into using step or progress of the animate method:
$('body').animate({ scrollTop: 0 }, {
duration: 'slow',
step: function(now, fx) {
lastScrollTop = now; //Get the current scroll amount.
},
complete: function() {
lastScrollTop = $(this).scrollTop();
}
});
now: the numeric value of the property being animated at each step
fx: a reference to the jQuery.fx prototype object, which contains a number of properties such as elem for the animated element, start and end for the first and last value of the animated property, respectively, and prop for the property being animated.
Use step if you want to get the value before the animation happens, and use progress if you want the value after it happens. Something like this:
$('html,body').animate(
{scrollTop: 0},
{
'slow',
step: function(currentTop){
console.log (currentTop)
}
},
function(){
lastScrollTop = $(this).scrollTop();
}
);
Related
Here is the current code I have for clicking buttons and having it scroll through and change a few things.
$(".scroll").click(function(event) {
$('.panel h1').stop().fadeOut(200);
$('.panel p').stop().fadeOut(200);
$(".scroll").css({"background": "none", "color": "#B1B1B1"});
$(this).css({"background": "#00709C", "color": "#fff"});
event.preventDefault();
$('.scroll-menu').stop().animate({
scrollLeft: $('.scroll-menu').scrollLeft() + $(this.hash).offset().left
}, 1200);
$('.panel h1').delay( 900 ).fadeIn(500);
$('.panel p').delay( 900 ).fadeIn(500);
});
I got a little help, so actually I'm confused as to what $(this.hash).offset().left is referring to.
Also, can anyone give me an idea as to how to automatically animate this without an on click? For instance, this does NOT work.
setInterval(function() {
$('.scroll-menu').stop().animate({
scrollLeft: $('.scroll-menu').scrollLeft() + $(this.hash).offset().left
}, 1200);
$('.panel h1').delay( 900 ).fadeIn(500);
$('.panel p').delay( 900 ).fadeIn(500);
}, 3600);
Sure, here you go: http://jsfiddle.net/neuroflux/afzVe/617/
and the relevant code:
$('#scroll').click(function() {
$('html,body').animate({
scrollLeft: $('#test').css('left')
}, 800, function() {
$('html, body').animate({
scrollLeft: 0
}, 800);
});
});
Say you have an anchor tag like one below:
Some anchor
this.hash on anchor click will return "#foo" which is also a valid ID selector. Hence $(this.hash) is the same as $("#foo") and will select the element with ID - foo and $(this.hash).offset().top basically returns top of element #foo
Regarding your 2nd question its quite unclear as to on what instance you want to animate automatically but still in your setInterval since you are referring $(this.hash) and since its not a valid element there you can first try keeping element in variable and then apply the hash functionality like one below:
var elem=$(".scroll");//store it globally
setInterval(function() {
$('.scroll-menu').stop().animate({
scrollLeft: $('.scroll-menu').scrollLeft() + $(elem.hash).offset().left
}, 1200);
$('.panel h1').delay( 900 ).fadeIn(500);
$('.panel p').delay( 900 ).fadeIn(500);
}, 3600);
I am trying to move the slide once every time that I make scroll in the page. But scroll event doesn't stop and repeat the event. How can I make an animation to move to the next slide color with scrollTop inside $(window).scroll just once for every time? See my Fiddle
And this is the piece of code which doesn't work :(
$('html, body').animate({
scrollTop: ($(next).offset().top)
},500);
My target is something like that http://www.sincedilla.com/
this is probably what you need.
The scroll event ve to be prevented until the animation is finished ,
docs for animation http://api.jquery.com/animate/ read the callback section
$(this).bind('mousewheel', function (e) {
if (!animating) {
animating = true;
if (e.originalEvent.wheelDelta < 0) {
next = $(first).next();
first = $(next);
// scroll down
$("html, body").animate({
scrollTop: ($(next).offset().top)
}, 900, function(){
animating = false;
});
} else {
first = $(next).prev();
next = $(first);
// scroll up
$("html, body").animate({
scrollTop: ($(first).offset().top)
}, 900,function(){
animating = false;
});
}
}
return false;
});
working fiddle http://jsfiddle.net/fdbh0no8/
So I have the following code:
$("#btn1").click(function(event) {
event.preventDefault();
$('html, body').animate({
scrollTop: $("#div").offset().top
}, 2000);
$("#div").addClass("flash");
setTimeout( function(){
$("#div").removeClass("flash"), 1000;
}, 1000);
});
When I click on the button it will scroll down to the div and flash its color (flash class). But what if the div is at the bottom of the page? I need the ode above to be changed so that the scrollTop is executed first AND is finished and then execute the next piece of code (the addClass and the setTimeout function). I assume I need to add a delay? Or something that checks whether the function is complete and if so, start the next one?
I think what you're looking for is animation callback. It's the forth parameter to the .animate() method: http://api.jquery.com/animate/
So in your case it would look like this:
$("#btn1").click(function(event) {
event.preventDefault();
$('html, body').animate({
scrollTop: $("#div").offset().top
},
2000,
'swing',
function () {
$("#div").addClass("flash");
setTimeout( function(){
$("#div").removeClass("flash"), 1000;
}, 1000);
});
});
Btw. it's a good practice to cache a jQuery selectors for optimisation (jQuery won't be searching the DOM for the queried nodes, and running the its constructor function each time).
I also refactored this code a bit for readability and to separate the flashing functionality, so you can either use it conveniently in such callbacks (in which case the function will get the animated element as this object, or just run it directly, passing it any jQuery element (e.g. flash($('.anything')))
$("#btn1").click(function(event) {
event.preventDefault();
$div = $('#div');
$('html, body').animate({
scrollTop: $div.offset().top
}, 2000, 'swing', flashElement});
});
function flashElement(element) {
element = element || this;
element.addClass("flash");
setTimeout( function(){
element.removeClass("flash"), 1000;
}, 1000);
}
You just need a callback...
$("#btn1").click(function(event) {
event.preventDefault();
$('html, body').animate({
scrollTop: $("#div").offset().top
}, 2000, function(){
$("#div").addClass("flash");
setTimeout( function(){
$("#div").removeClass("flash"), 1000;
}, 1000);
});
});
In my game I am going to add obstaceles that move left to right across the <div id="outline"></div>
I've used setInterval(){...} with the .animate() In it, and it seems to work only issue is after a little bit of time it leaves the ouline, Below is some code and a link.
$(document).ready(function() {
setInterval(function(){
$("#CObject").animate({
'marginLeft' : "+=220px" //moves left
}, 900);
}, 900);
setInterval(function(){
$("#CObject").animate({
'marginLeft' : "-=220px" //moves left
}, 900);
}, 1000);
});
Link.
change to this on your "-=220px":
setInterval(function(){
$("#CObject").animate({
'marginLeft' : "-=220px" //moves left
}, 900);
}, 900);
to match 900 time interval, it's offset by 100.
If you want to know. There's another way do what you want without use setInterval, in this case you have to wait the animation ends in order to start the reverse animation.
$(document).ready(function() {
animate(false);
});
function animate(reverse) {
$("#CObject").animate({
'marginLeft' : (reverse) ? "-=220px" : "+=220px" //moves left
}, 900, function() {
// Run when animation finishes
animate(!reverse);
});
}
This way you can be sure that animation will finish before start anything else
Without setInterval:
$(document).ready(function() {
function loop() {
$("#CObject").animate({
'marginLeft' : "+=220px" //moves left
}, 900, 'linear', function() {
loop();
});
$("#CObject").animate({
'marginLeft' : "-=220px" //moves left
}, 900, 'linear', function() {
loop();
});
}
loop();
});
fiddle
create a loop function with the animation and then just call it when the animation finishes.
To ensure that the animation is complete, I would just have each direction animation call the other one when it completes. If you look at the API for animate, you'll see the fourth parameter is for a function that will be called when the animation is finished. http://api.jquery.com/animate/
$(document).ready(function() {
animateRight();
});
function animateRight() {
$("#CObject").animate({
'marginLeft' : "+=220px" //moves left
}, 900, 'swing', animateLeft);
}
function animateLeft() {
$("#CObject").animate({
'marginLeft' : "-=220px" //moves right
}, 900, 'swing', animateRight);
}
Here is the fiddle: http://jsfiddle.net/cgdtfxxu/
a couple of people kindly helped me yesterday with a jQuery issue on a scrollTop function but I now have another small issue. Below is the fiddle for the js. I need to get the js to bounce the content back to the top instead of scrolling back up to the top.
Here is the JS, fiddle below it.
function scroll(speed) {
$('.shooter-scroller').animate({
scrollTop: $('.shooter-scroller').prop('scrollHeight'),
easing: 'linear'
}, {
duration: speed,
easing: 'linear', // <--- here
complete: function () {
$(this).animate({
scrollTop: 0
}, {
duration: speed,
easing: 'linear', // <--- here
complete: speed
});
}
});
}
speed = 8000;
scroll(speed)
setInterval(function () {
scroll(speed)
}, speed * 2);
});
fiddle
I need the speed to remain as linear but the scroll to reset to the top once it gets to the bottom. Any help would be amazing! Thanks in advance people :)
Here is an updated fiddle: http://jsfiddle.net/tsb5pj49/4/
Instead of animating it back to the top, you can just set the scrollTop to 0 using the same function. Additionally, if you store the setInterval in a variable then you can clear it and start it again when the animation completes and the scrollTop is reset. Like so:
// When DOM is fully loaded
jQuery(document).ready(function ($) {
var speed = 8000,
scrollInterval;
function scroll(speed) {
$('.shooter-scroller').animate({
scrollTop: $('.shooter-scroller').prop('scrollHeight'),
easing: 'linear'
}, {
duration: speed,
easing: 'linear', // <--- here
complete: onScrollingComplete
});
}
function startScrolling() {
scroll( speed );
scrollInterval = setInterval(function () {
scroll(speed)
}, speed * 2);
}
function onScrollingComplete() {
$( this ).scrollTop( 0 );
clearInterval( scrollInterval );
startScrolling();
}
startScrolling();
});
Hope this helps