I have a page that auto scrolls - the function scroll() below worked just fine.
I needed to add an on-hover function - which should pause the scrolling, giving the user control over the scroll.
I added some code to stop scrolling on-hover.
<script>
var theInterval;
function startScroll() {
theInterval = setInterval(scroll, 50);
}
function stopScroll() {
clearInterval(theInterval);
}
$(function () {
scroll();
$('#scrollDiv').hover(function () {
stopScroll();
}, function () {
startScroll();
})
});
function scroll() {
if (document.getElementById('scrollDiv').scrollTop < (document.getElementById('scrollDiv').scrollHeight - document.getElementById('scrollDiv').offsetHeight)) {
-1
document.getElementById('scrollDiv').scrollTop = document.getElementById('scrollDiv').scrollTop + 1
}
else { document.getElementById('scrollDiv').scrollTop = 0; }
}
setInterval(scroll, 50);
</script>
I expected that the extra functions would stop the scrolling when the user hovers over the content.
What happened was that the scrolling simply stopped
You are dropping the interval pointer from your initial call to scroll. setInterval returns an ID to the timer that is running the function at the specified cadence.
Your code is kicking off the scrolling on the last line, but not capturing this timer ID to clear -- so on 1st hover you clear a null pointer in theInterval, then on blur you're starting another timer calling scroll.
You probably notice that it gets faster because 2 logic paths are now adding 1px every 50 ms.
On the last line, you need to also set theInterval to keep track of that call, like:
theInterval = setInterval(scroll, 50)
That should fix it.
Related
I'm working on a project and I need to create a vertical carousel that works on scroll (mousewheel) I just need to know how can I handle the sliding on scroll.
I have a function called nextSlide when I call then it get the next slide.
I did something like this (I checked the direction and other stuff but I'm adding the simplest code snippet here)
Note: I did Debounce on my function but it didn't work
el.addEventListener('wheel', (event) => {
event.preventDefault();
nextSlide();
});
The problem here is the event firing on each mouse scroll I just need to handle it on one scroll here is an example from swiper
https://codepen.io/Seamni69/pen/vYgmqVd
What I meant by one scroll is calling the function just one time when scrolling, no matter how much scrolling is.
Created this. if wheelDeltaY is positive, you are scrolling down. If it's negative you are scrolling up.
window.addEventListener('wheel', throttle(scrollDirection, 500));
function scrollDirection(e) {
e.preventDefault();
e.wheelDeltaY > 0
? console.log("DOWN")
: console.log("UP")
e.stopImmediatePropagation();
};
function throttle(func, interval) {
let lastCall = 0;
return function() {
const now = Date.now();
if (lastCall + interval < now) {
lastCall = now;
return func.apply(this, arguments);
}
};
}
I'm trying to make a simple Javascript/Jquery program which will cycle through a product carousel I have on the front page of a website.
Here is the code:
jQuery(document).ready( function() {
function next() {
if(window.location.href === window.location.origin + '/') {
var nextButton = jQuery('.prevSlide');
nextButton.trigger('click');
console.log('next');
return;
}
}
function prev() {
if(window.location.href === window.location.origin + '/') {
jQuery('.nextSlide').click();
console.log('prev');
return;
}
}
jQuery('.iosSlider').hover( function() {
jQuery(this).addClass('pauseInterval');
}, function () {
jQuery(this).removeClass('pauseInterval');
}
);
function cycleNext() {
if( !(jQuery('.prevSlide').hasClass('disabled'))) {
if( !(jQuery('.iosSlider').hasClass('pauseInterval'))) {
next();
}
} else {
clearInterval(interval);
intervalTwo = setInterval(cyclePrev, 2000);
console.log('interval cleared');
console.log('intervalTwo set');
return;
}
}
function cyclePrev() {
if( !(jQuery('.nextSlide').hasClass('disabled'))) {
if(!(jQuery('.iosSlider').hasClass('pauseInterval'))) {
prev();
}
} else {
clearInterval(intervalTwo);
var interval = setInterval(cycleNext, 2000);
console.log('intervalTwo cleared');
console.log('interval set');
return;
}
}
var interval = setInterval(cycleNext, 2000);
console.log('interval set');
});
In each of the next() and prev() functions, I check whether I am on the home page, and only proceed if so.
There is also some code there to pause the cycle if the mouse is hovering over the product slider.
When the slider is at the very start or end, a class called 'disabled' is added to the prevSldie and nextSlide anchors.
So ideally I want to click through to the end of the slider, and then click back to the start, then the end, etc.
So the control flow, as I understand it, is as follows:
An interval is set so that the next button on my carousel is clicked every two seconds.
The slider reaches the end, that interval ends and a new one is set.
The previous button is clicked every two seconds until the start of the carousel.
This process repeats infinitely.
Things run fine when the slider runs to the end, the start, and the end again, and then things go haywire.
Console output (should click next and prev 5 times each)
(5) next
interval cleared
intervalTwo set
(5) prev
intervalTwo Cleared
interval set
(5) next
interval cleared
intervalTwo set
interval cleared
intervalTwo set
prev
next
(2) prev
next
(2) prev
next
And it only gets more haywire all over the place from there.
I cant figure out why everything works fine for the first few loops and stops working after that, any help would be hugely appreciated.
Are your intervals scoped correctly? You never define intervalTwo, so it becomes a global. Then also in the cyclePrev function, you use var interval again, which will be scoped to this function and hence won't contain the interval outside the function, that you want to clear once cycleNext gets reached again. Try changing:
var interval = setInterval(cycleNext, 2000),
intervalTwo = null;
console.log('interval set');
And then change var interval = setInterval(cycleNext, 2000); inside cyclePrev into interval = setInterval(cycleNext, 2000);
I have setInterval problem. I made something similar to load bar. When I click mouse I fire expanding width of my block called loadBar1
// here preset of interval and loadbar...
var interval = 0;
createLoadBar1 = function() {
loadBar1 = {
// another stuff
width:0,
};
document.onclick = function (mouse) {
interval = setInterval(expandLoadBar1, 60);
}
It's expands by the help of this function:
function expandLoadBar1() {
if(loadBar1.width < 60) {
loadBar1.width++;
}
if (loadBar1.width >= 60) {
loadBar1.width = 0;
clearInterval(interval);
}
}
It's very simple above and works well when I click just once but I start having problems when I click more that one time by mouse clicking, it's logically cause the faster loadBar1.width expanding twice and after second or more mouse click the clearInterval for interval stops working and just continue raising expanding speed when I click more.
You probably need to clear the interval when the user clicks:
document.onclick = function () {
clearInterval(interval);
interval = setInterval(expandLoadBar1, 60);
}
I have this istuation. I have a setTimeout to a function in which I fade out and fade in an element. In a few seconds this timeout is cleared with cleartimeout and right after is called .hide() to hide this element. The problem is that sometimes it doesnt hide the element. I have a feeling it has something to do with timing.
Example:
function first_func(){
$('.element').fadeOut(function(){
// Do other stuff like change element's position
$('.element').fadeIn();
});
interval1 = setTimeout(function(){first_func()},500);
}
function second_func(){
countdown--;
if (countdown<0){
last_func();
}
interval2 = setTimeout(function(){second_func()},1000);
}
function begin_func(){
first_func();
second_func();
}
function last_func(){
clearTimeout(interval1);
clearTimeout(interval2);
$('.element').hide();
}
So basically the problem is that in last_func I clear both intervals and HIDE the element, but sometimes the element is still visible on the page. So I am guessing that it does hide but the interval is still in progress and it fades back in.
If anyone would have some suggestion please
Just a suggestion, but this bit appears wrong to me:
function second_func(){
countdown--;
if (countdown<0){
end_func();
}
interval2 = setTimeout(function(){second_func()},1000);
}
Even if you're calling end_func() to stop everything, you're setting a new timeout after that.
function second_func(){
countdown--;
if (countdown<0){
end_func();
} else {
interval2 = setTimeout(second_func, 1000);
}
}
Another hint: To avoid that running fadeIn/fadeOuts affect the hiding of the element, you should clear the animation queue:
$('.element').stop(true, true).hide();
By default fadeIn and fadeOut use duration of 400 milliseconds, u can change it by set first parameter.
$('.element').fadeOut( [duration] [, callback] );
You seem to never call last_func, is end_func() supposed to be last_func()?
This works:
http://jsfiddle.net/CZ9hr/1/
May I suggest a simpler approach for what you seem to want to achieve: http://jsfiddle.net/fSEjR/2/
var countdown = 3,
$element = $('.element');
for (var i = 0; i < countdown; i++) {
$element.fadeOut().fadeIn(function() {
countdown--;
if (countdown === 0) $element.hide();
});
};
This works because animations are automatically queued in jquery.
I'm using JS to animate two images by having them toggle on and off. I have an initial image which, when the animation is turned on, appears on the screen and stays on. The second image, which has a higher z value, is then set to toggle on and off every 1 second in the same location as the first image, so it appears as if the two are alternating.
I'm using window.setInterval to make the second image blink, but when I need to turn the animation off (and I'm removing both images from the screen), my window.clearInterval is not "working" The first image will be gone, but the second one keeps blinking on and off every second.
Code:
function notebookNotification(setting)
{
$("#lightNotificationContainer").show();
var notificationAnimation = window.setInterval('$("#darkNotificationContainer").toggle()', 1000);
if(setting == 0)
{
window.clearInterval(notificationAnimation);
$("#lightNotificationContainer").hide();
$("#darkNotificationContainer").hide();
}
}
Anyone see why it isn't working?
Reading between the lines, I think what you're saying is this:
You execute notebookNotification(1); and the animation starts
You execute notebookNotification(0); and the animation does not stop.
My guess is that you want notebookNotification(0) to disable the flashing.
In order to do that, you need to rework this function considerably. You need to store the intervalID that comes from setInterval in a variable that survives outside of the scope of this function and can be used for clearInterval on subsequent calls to this function.
For example:
var intervalID;
function notebookNotification(setting)
{
if(setting == 0)
{
if(intervalID) {
window.clearInterval(intervalID);
intervalID = null;
}
$("#lightNotificationContainer").hide();
$("#darkNotificationContainer").hide();
}
else
{
$("#lightNotificationContainer").show();
if(!intervalID) {
intervalID = window.setInterval('$("#darkNotificationContainer").toggle()', 1000);
}
}
}
Here, try this:
http://jsfiddle.net/WGxmy/
Saving the interval to a global variable -- not one inside a function -- lets you clear it later.
var keepflashing = true;
var isShowing = true;
function notebookNotification()
{
if(!isShowing)
$("#lightNotificationContainer").show();
else
$("#lightNotificationContainer").show();
isShowing = !isShowing;
if(keepflashing)
setTimeout( function(){ notebookNotification(setting); },100);
else
{
$("#lightNotificationContainer").hide();
$("#darkNotificationContainer").hide();
}
}
Maybe you can avoid calling clearInterval() generally?
function notebookNotification(setting)
{
if(setting == 0)
{
$("#lightNotificationContainer").hide();
$("#darkNotificationContainer").hide();
}
else
{
$("#lightNotificationContainer").show();
window.setInterval('$("#darkNotificationContainer").toggle()', 1000);
}
}