On click on an element I do scrolling:
isScrolling = true;
$('html, body').animate({
scrollTop: $(target_elem).offset().top - 100
}, "fast", function(){
// set isScrolling = false
myTimeout = setTimeout(resetScrolling, 500);
});
Meanwhile a CSS animation is executing. I couldn't set isScrolling immediately after scrolling complete and want to wait a little for CSS animation done.
How can I do this? I tried to use a setTimeout, but it seems it doesn't work properly and I want to kill such timers if user repeatedly click on the element...
Related
I am trying to perform a simple animation that I would like to happen after a successful return of an AJAX call.
$('#result').click(function(){
$(document).ajaxSuccess(function(){
$('html, body').on("scroll mousedown wheel DOMMouseScroll mousewheel keyup touchmove", function(){
$('html, body').stop();
});
$('html, body').animate({
scrollTop: $('#result').position().top
}, 500, function(){
$('html, body').off("scroll mousedown wheel DOMMouseScroll mousewheel keyup touchmove");
});
});
});
The problem is that sometimes, not always, the animation does not seem to want to exit in that it causes jerky movements and a constant return to the top of the div if the user attempts to scroll away. When I remove the ajaxSuccess requirement, the problem does not occur. Any ideas?
There is no need to stop mousewheel, scroll etc. movement by using stop() function.
animate function won't be disturbed until it has reached the document top.
This would do:
$('#result').click(function(){
$(document).ajaxSuccess(function(){
$('html, body').animate({
scrollTop: $('#result').position().top
}, 500);
});
});
You're attaching a new ajaxSuccess callback every time the user clicks on #result.
This means that if the user clicked on #result N times, then N different functions are attached to be executed whenever an ajax request completes successfully. And each function will try to animate $('html, body')
Solution: Move your code out of $('#result').click function or unbind previous handlers before binding a new one.
And here is the simplified example of what is happening. Try to click two buttons one after another:
$("#one").click(() => {
console.log("Clicked First")
$("#two").click(() => console.log("Clicked Second"));
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id=one>First</button>
<button id=two>Second</button>
I am writing code for when a button is clicked it will animate going to a certain spot on the page. The problem is the first time I execute the code it is very laggy on the scrollTop animation. I am using w3schools code so I was surprised it was not working.
Here is the code I am using to animate the scrolling:
// Add smooth scrolling to all links
$("a").on('click', function (event) {
// Make sure this.hash has a value before overriding default behavior
if (this.hash !== "") {
// Prevent default anchor click behavior
event.preventDefault();
// Store hash
var hash = this.hash;
// Using jQuery's animate() method to add smooth page scroll
// The optional number (400) specifies the number of milliseconds it takes to scroll to the specified area
$('html, body').animate({
scrollTop: $(hash).offset().top
}, 500, function () {
// Add hash (#) to URL when done scrolling (default click behavior)
window.location.hash = hash;
});
} // End if
});
I want a scroll event listener to fire when the user scrolls the page for the first time, but then to stop firing after a certain amount of time and just allow the user to scroll normally.
Here's how I've currently got it working:
var scrollcount = 0
// Scroll event listener
window.addEventListener("scroll", function() {
setTimeout(function() {
scrollcount ++
if (scrollcount < 40) {
window.scrollTo(0, 0);
}
}, 1200);
});
The scrollcount variable increments along with scrolling, and 40 is about how much it takes for one scroll up on my laptop's trackpad. If the counter is under 40, the page scrolls back up to the top of the page once the user lets go of the scroll wheel, if it's over 40 it doesn't.
I realise that this is a really bad way to go about this, so I'm wondering if anyone has a more reliable way to do it. I tried to have a removeEventListener method turn off the event listener once setTimeout has finished its delay, but I couldn't get it to target the window. I think removeEventListener would work if the scroll event listener was assigned to a container div, and not the window, but when I tried that the scroll event listener wouldn't work in the first place.
I wanted to avoid jQuery or any other library if I could, but at this point I'll use anything that gets it to work reliably.
You need to give a name to your listener to remove it:
var scrollcount = 0
// Scroll event listener
function scrollListener() {
setTimeout(function() {
scrollcount ++
if (scrollcount < 40) {
window.scrollTo(0, 0);
window.removeEventListener("scroll", scrollListener);
}
}, 1200);
});
window.addEventListener("scroll", scrollListener);
This will jump to the top of the page, after 2 sec from when user start scrolling:
/* Create a one-time event */
function onetime(node, type, callback) {
node.addEventListener(type, function(e) {
e.target.removeEventListener(e.type, arguments.callee);
return callback(e);
});
}
onetime(document, 'scroll', function(e) {
setTimeout(function(){ window.scrollTo(0, 0); }, 2000);
});
see it live here
If you are using jQuery, you can use jQuery's one function, and simplify the code to:
$(document).one('scroll', function(e) {
setTimeout(function(){ window.scrollTo(0, 0); }, 2000);
});
If you want to jump to the top of the page after some animations are finished instead of waiting predefined amount of time, then you should call window.scrollTo(0, 0); after you are done animating. If you are animating using jQuery's effect functions, then you can pass callback function as last argument, and it will be called once the animation is complete. For example you can do something like this:
$(document).one('scroll', function(e) {
$('pre').animate(
{fontSize: "106px"},
2000,
function(){ window.scrollTo(0, 0); }
);
});
see it live here
I am trying to use .hover() to hide and show the options while user mouse in the image.
Here is my JS code:
$(document).ready(function(){
$('#test').hover(
function(){
$('.caption').show('slide', {direction: 'left'}, 1200);
},
function(){
$('.caption').hide(1200)});});
Right now the animation works, but if I mouse enter and mouse out multiple times quickly, the speed of the repetition of the tag cannot catch up with the mouse. And I want while I hover again, the incomplete animation could pause what its doing and execute the present calling.
I tried to add a .stop() but then the function could not repeat while I mouse in again anymore
Does anyone know how to do it, thanks.
Here is the JSFiddle: http://jsfiddle.net/x69chen/aznEa/2/
use stop(true,true) in Jquery.We can use create a nice slide effect without the
common problem of multiple queued animations by adding .stop(true,
true) to the chain:
$(document).ready(function(){
$('#test').hover(
function(){
$('.caption').stop(true,true).show('slide', {direction: 'left'}, 1200);
},
function(){
$('.caption').stop(true,true).hide(100)});
});
Use $('.caption').clearQueue() on mouse out.
This will clear the current animation under process
Refer :http://api.jquery.com/clearQueue/
// try this
$(document).ready(function(){
$('#test').hover(
function(){
$('.caption').show('slide', {direction: 'left'}, 1200);
});
$('#test').mouseout(function(){
$('.caption').stop().show('slide', {direction: 'left'}, 1200);
$('.caption').hide(100);
});
});
see js fiddle at http://jsfiddle.net/x69chen/aznEa/2/
I'm animating a scroll to effect using jQuery, after the animation ends, I trigger an effect, for some reason the effect is triggered twice, how can I prevent it from happening?
$('.something').on('click', function() {
$('html, body').animate({
scrollTop: $('footer').offset().top
}, {
queue: false,
duration: 1500,
complete: function() {
$('.foo').toggleClass('active');
$('.bar').slideToggle();
}
});
return false;
});
The slideToggle effect seems to be triggered twice.
I have it animate on html & body because animate from 'body' doesn't work in IE8.
Since you're triggering two animations (on html and body) the complete callback should be called twice.
You might want to on trigger the animation on html only if it's required
var animateOn = isIE8 ? 'html' : 'body';
$(animateOn).animate();