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();
Related
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...
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>
Having some problems with JavaScript / jQuery.
We're currently using a "shortcode" from Visual Composer (WordPress plugin) that creates (horizontal) tabs. We'we made some custom changes, but only visually (images/css).
We're trying to make it so that when you click on a tab you automatically scroll down to the content.
I've tried wrapping the script in
jQuery(document).ready( function({});
jQuery(window).ready( function({});
and also tried replacing .ready() with .load()
jQuery(".pws_tabs_controlls_item").children().click(function(){
jQuery('html, body').animate({
scrollTop: jQuery(".ts-fancy-tabs-container").offset().top
}, 700, 'swing', function () {});
});
However! If you copy the entire script and paste it in the Console in Chrome/Firefox it will work as intended, based on that I'd say that the script it self works, it feels like it's not loading or registering or w/e.
Is there any (obvious) problem/mistake we've made?
I'd be happy to provide additional information if neccessary (e.g. the website address)
Any help would be greatly appreciated!
The VisualComposer plugin renders only after the document is ready, and that's why it's not working.
The best way to solve your problem is by using jQuery's event delegation, e.g:
jQuery(document).on('click', '.pws_tabs_controlls_item > a', function() {
jQuery('html, body').animate({
scrollTop: jQuery(".ts-fancy-tabs-container").offset().top
}, 700, 'swing', function () {});
});
UPDATE
After your comment, I can see that the anchor tags inside your .pws_tabs_controlls_item elements already have a click event listener, and it also uses event.stopPropagation(), so my code above will never be executed.
The other way to solve your problem, is by dirty-checking when the element is available, e.g:
function waitForAvailability(selector, callback) {
if (jQuery('selector').length === 0) {
callback();
}
else {
setTimeout(function() {
waitForAvailability(selector, callback);
}, 0);
}
}
And then, you can use the code you were already using, something like that:
waitForAvailability('.pws_tabs_controlls_item', function() {
jQuery(".pws_tabs_controlls_item").children().click(function(){
jQuery('html, body').animate({
scrollTop: jQuery(".ts-fancy-tabs-container").offset().top
}, 700, 'swing', function () {});
});
});
I have read this is the correct way to get scroll to and animation working in Jquery with the body and html tags. However, this also fires the callback multiple times event if $("body, html") shows only two items in a list. At the most I would think 2, after each iteration it can go up which I'm not sure why, but I need to execute the callback one time with his setup? Any fix?
$("body, html").animate({ scrollTop: top }, function () {
animateScroll($topItem);
});
With $("body, html") you're selecting two elements to animate, first body and second html. That's because two callbacks are fired, just like it should be.
See explanation here: Callback of .animate() gets called twice jquery
Try to change your code as follows:
$("html body").animate({ scrollTop: top }, function () {
animateScroll($topItem);
});
you can try this workaround:
var callbackFired=false;
$("body, html").animate({ scrollTop: top }, function () {
if(!callbackFired){
animateScroll($topItem);
callbackFired=true;
}
});
This did it for me.
$("body, html").animate({ scrollTop: top }).promise().done(function() {
animateScroll($topItem);
});
I have a portion of jQuery that just doesn't seem to be working correctly. I have a link to click, [show/hide] which should slideToggle a div. At the same time, I want to animate it so that the page scrolls to the top of the div. It works when I put the animate function inside the slideToggle function, like in this jfiddle.
However, this means that the div i want slides out, and then the page scrolls down. id like to set it up so that both happen simultatneously, which I tried to do in this jfiddle but it simply doesn't work. I also tried doing the scroll animation first, then the slideToggle, which didn't work - is there a way to implement this also?? Cheers!
$(document).ready(function () {
$('.click_to_hide').click(function () {
var visible = $('.hide_on_click').is(":visible");
$('.hide_on_click').slideToggle(500);
if (!visible) {
$('html, body').animate({
scrollTop: $('.hide_on_click').offset().top
}, 500);
}
});
});
http://fiddle.jshell.net/YFR2e/3/
$(document).ready(function () {
$('.click_to_hide').click(function () {
$('.hide_on_click').slideToggle(500);
if($('.hide_on_click').is(':visible')){
$('html, body').animate({
scrollTop: $('.hide_on_click').offset().top
}, 500);
}
});
});
try to put it in the same function