jQuery - stop/cancel scroll event callback after a certain scroll position - javascript

I want the number to count up to its designated value and stay there, but because the function gets called every time the page is being scrolled below a certain height, then it goes back to 1.
The solution would be to make it call the function only once when the page has been scrolled to below the certain height.
Ive tried placing the .one() method several places but that didn't help
http://jsfiddle.net/d7vKd/1543/
$(document).on('scroll', function() {
if ($(this).scrollTop() >= $("#mydiv").position().top) {
window.randomize = function() {
$('.radial-progress1').attr('data-progress', Math.floor(94));
};
$('.count').each(function() {
$(this).prop('Counter', 0).animate({
Counter: $(this).text()
}, {
duration: 6000,
easing: 'swing',
step: function(now) {
$(this).text(Math.ceil(now));
}
});
});
setTimeout(window.randomize, 200);
}
})

You should unbind your scroll event once the callback has met its demands:
$(document).on('scroll.someName', function(){
var isPassedPos = $(this).scrollTop() >= $("#mydiv").position().top;
if( isPassedPos ){
$(document).off('scroll.someName') // <-------------- remove the event listener
window.randomize = function() {
$('.radial-progress1').attr('data-progress', Math.floor(94));
};
$('.count').each(function() {
$(this).prop('Counter', 0).animate({
Counter: $(this).text()
}, {
duration: 6000,
easing: 'swing',
step: function(now) {
$(this).text(Math.ceil(now));
}
});
});
setTimeout(window.randomize, 200);
}
})

Related

How to trigger jQuery counter when element is in window?

I have this jQuery code that triggers a counter from 0 to 1750. But, this counter is at the bottom of my page, and if you don't scroll to it quickly enough you miss the counter animation. Is there a way to trigger this to run only once you've hit the element in the window?
// Counter
$(document).ready(function() {
$('.count').each(function() {
$(this).prop('Counter', 0).animate({
Counter: $(this).text()
}, {
duration: 12000,
easing: 'swing',
step: function(now) {
$(this).text(Math.ceil(now));
}
});
});
});
Try something like this, check your window top position and if is higher or equal of your target element and less the window height, then do your count animation.
HTML
<div class="wrapper-count">
<ul>
<li class="count">0</li>
<li class="count">0</li>
<li class="count">0</li>
</ul>
</div>
JS
$(document).ready(function(){
$(function(){
$(window).on("scroll", function(){
var win_height = $(this).height();
var win_pos = $(this).scrollTop();
var top_pos = $(".wrapper-count").position().top;
if(win_pos >= top_pos - win_height){
// here goes your count logic
}
});
});
});

Not repeating the function once waypoint reached

Here is the JS for the waypoint call and graph bar function. It repeats every time the waypoint is reached and I would like it to recognise that the waypoint has been reached once already ad not to repeat function. Thanks for your help. :)
$.getScript('http://imakewebthings.com/jquery-waypoints/waypoints.min.js', function() {
$('#jack_bellamy').waypoint(function() {
setTimeout(function start (){
$('.bar').each(function(i)
{
var $bar = $(this);
$(this).append('<span class="count"></span>')
setTimeout(function(){
$bar.css('width', $bar.attr('data-percent'));
}, i*100);
});
$('.count').each(function () {
$(this).prop('Counter',0).animate({
Counter: $(this).parent('.bar').attr('data-percent')
}, {
duration: 2000,
easing: 'swing',
step: function (now) {
$(this).text(Math.ceil(now) +'%');
}
});
});
}, 500)
});
});
If you don't want a waypoint to keep triggering you can destroy it. To ensure it only runs once, you can destroy it at the end of your handler. The this keyword refers to the waypoint instance you can call destroy on within the handler.
$('#jack_bellamy').waypoint(function() {
// all that animation stuff you mentioned
this.destroy();
});

jquery stop() not working when combining jquery fade and slide jquery-ui

I used the following javascript:
$('.slide-content #show-effect-1').hover(function(){
$(this).next().stop(true, true).fadeIn({ duration: _duration, queue: false }).css('display', 'none').show('slide', { direction: "down" }, _duration);
},
function() {
$(this).next().stop(true, true).fadeOut({ duration: _duration, queue: false }).hide('slide', { direction: "down" }, _duration);
});
What should happen is:
mouseenter the button --> content show
mouseout the button --> content hide
Question: when mouseout on the button is faster than the effect time of mouseenter, the content will be hidden and not displayed when mousenter the button again.
How do I prevent this happening?
Instead of using separate funcitons for the fadeIn and slide effect I decided to implement both in a single animate() function, then I just added some CSS resets to make sure the element is ready before starting the animation:
$(document).ready(function () {
var _duration = 1000;
$('#show-effect-1').hover(function () {
var $next = $('.text-banner');
$next.show();
$next.stop(true, true).css({
'margin-left': $next.outerWidth() * -1,
'margin-top': 0,
'opacity': 0,
'display': 'block'
}).animate({
'margin-left': 0,
'opacity': 1
}, _duration);
}, function () {
var $next = $('.text-banner');
$next.stop(true, true).animate({
'margin-top': $next.height() * -1,
'opacity': 0
}, _duration, function () {
$(this).hide();
});
});
});
Check the Updated fiddle
Note that I had to add a container to accurately reproduce the slide effect, you can test without it and see if it's something you actually need

Halting fade animation when clicking a new element

I have an animation that causes boxes to appear in sequence when clicking a link. I'm finding that the animation does not stop when clicking a new link and will often cause the it to appear out of sequence. You can see this here when clicking between guests rapidly. I thought something like $.animation.stop() would solve the issue but it hasn't. Any help would be appreciated.
var stepFade = function() {
if ($($this).data("known1") === undefined || null) {
$('.guest-data .known-for').css('display', 'none');
} else {
$('.guest-data .known-for').css('display', 'block');
$('.guest-data .known-for li').eq(0).delay(200).fadeIn( 300);
$('.guest-data .known-for li').eq(1).delay(300).fadeIn( 300);
$('.guest-data .known-for li').eq(2).delay(400).fadeIn( 300, function() { animating = false; });
}
}
//Fade guest
if (!featured) {
featured = true;
getData();
$('.featured').fadeOut( 500, function () {
$('.selected').animate({ opacity: 'toggle'}, 500, function() {
stepFade();
});
})
} else {
$('.selected, .guest-data .known-for, .guest-data .known-for li').fadeOut( 500, function () {
getData();
$('.selected').fadeIn( 500, function() {
stepFade();
});
});
}
Have you tried setting the queue option of .animate() to false?
This way, the animation won't be queued and will begin immediately:
$('.selected')
.animate({opacity: 'toggle'},
{duration: 500, queue: false,
complete: function() { stepFade(); }
});
...OR you could call .stop() right before you call .animate():
$('.selected')
.stop(true, false) //clear the queue and don't jump to the end
.animate({opacity: 'toggle'}, 500, function() {
stepFade();
});

bxSlider onAfterSlide callback

Good morning all :) I've got an issue here, which is pain in my neck for 2 days already. I'm using bxSlider for images to slide on a page and I'm calling my own function in onAfterSlide callback. Everything works fine except one thing. When I quickly switching between slides my function is being called 2-3 times(I have 3 images on page), which is not good as it returns unexpected results. I can not use newest version of bxSlider, because the markup has been changed. I think this happens, because the animation is still not finished when the onAfterSlide callback is called.
This is how I call bxSlider:
$('#slider_bx').bxSlider({
mode: 'fade',
speed: 1000,
pause: 9000,
auto: true,
autoControls: false,
prevText: '',
nextText: '',
autoHover: true,
captions: false,
pager: true,
onBeforeSlide: function () {
if ($('.slide_in').length) {
$('.slide_in').hide();
}
},
onAfterSlide: function () {
if ($('.slide_in').length && $('.slide_in').is(':hidden')) {
doCrazyStuff();
}
}
});
And this is my function:
function doCrazyStuff() {
var $this = $('.slide_in');
if ($this.length > 0) {
setTimeout(function () {
$this.show();
$this.rotate({
duration: 2000,
angle: 90,
animateTo: -20
});
}, 3000);
}
}
Any help appreciated. Thanks.
EDIT:
I've tried to add .stop(), but didn't helped.
$this.show().stop();
$this.stop().show();
$this.stop().rotate({
duration: 2000,
angle: 90,
animateTo: -20
});
$this.rotate({
duration: 2000,
angle: 90,
animateTo: -20
}).stop(); // throws an error
You can cancel a timeout or make a check to see if it's running.
If you want only the last timeout to run:
var crazyTimeout;
function doCrazyStuff() {
var $this = $('.slide_in');
if ($this.length > 0) {
if (crazyTimeout != undefined) {
clearTimeout(crazyTimeout); // Cancel previous timeout
}
crazyTimeout = setTimeout(function () {
crazyTimeout = undefined;
$this.show();
$this.rotate({
duration: 2000,
angle: 90,
animateTo: -20
});
}, 3000);
}
}
If you want only the first timeout to run:
var crazyTimeout;
function doCrazyStuff() {
var $this = $('.slide_in');
if ($this.length > 0) {
if (crazyTimeout != undefined) {
return; // A timeout is still running: don't create new one
}
crazyTimeout = setTimeout(function () {
crazyTimeout = undefined;
$this.show();
$this.rotate({
duration: 2000,
angle: 90,
animateTo: -20
});
}, 3000);
}
}
Try using the
$('.slide_in').stop()
in after slide function I hope it works, if possible try to give code in fiddle it will be easy to help.
Viewing your code I think the problem is not with your code : but as you have set auto to true so the plugin timer is not stopped and is sliding the images in its regular interval.
so I hope the use of stopAuto() bxSlider function in your custom function will solve the problem. and don't forget to start the auto show after you have finished doing your stuff.
thanks

Categories