Cant figuure out the control flow of my Javascript program - javascript

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);

Related

auto scroll stopped working when I added an an hover

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.

Javascript timer - How do I prevent the timer from speeding up each time .deck is clicked?

I am building a memory card game. the class .deck represents a deck of cards. Each time I click a card the timer speeds up. How do I prevent the timer from speeding up?
function startTimer() {
$(".deck").on("click", function () {
nowTime = setInterval(function () {
$timer.text(`${second}`)
second = second + 1
}, 1000);
});
}
You start multiple intervals, one each click. You probably should just start one. If you want to start it for the first card that is clicked:
function startTimer() {
// Maybe remove old timer? Should happen somewhere in your code.
// Possibly "stopTimer" if you have such a function.
clearInterval(nowTime);
let started = false;
$(".deck").on("click", function () {
if (started) return;
nowTime = setInterval(function () {
$timer.text(`${second}`)
second = second + 1
}, 1000);
started = true;
});
}
That code should have some more cleanup, though. Otherwise you accumulate a lot of dead event listeners.
(Furthermore, i believe that jQuery should never be used.)
You need to stop the previous timer before starting a new one because, if you don't, you wind up with multiple timer callback functions all executing one immediately after the other, which gives the illusion that your single timer is speeding up.
function startTimer() {
$(".deck").on("click", function () {
clearInterval(nowTime); // Stop previous timer
nowTime = setInterval(function () {
$timer.text(`${second}`);
second = second + 1;
}, 1000);
});
}
Another way to deal with this is to only allow the click event callback to run the very first time the button is clicked:
function startTimer() {
$(".deck").on("click", timer);
function timer() {
nowTime = setInterval(function () {
$timer.text(`${second}`);
second = second + 1;
}, 1000);
$(".deck").off("click", timer); // Remove the click event handler
}
}

fail to create function interval to prevent other function run

hello i try to create the function to prevent the other function to run for 10 minutes IF user close the content and refresh the page.
the other function is to show the content when we scroll with 2 argument
first: it will run the function with first argument with no interval, if user click close and refresh. it will run the second argument that give interval
heres my code.
https://jsfiddle.net/8c1ng49a/1/
please look this code
var popUp= document.getElementById("popup");
var closePopUp= document.getElementsByClassName('popup-close');
var halfScreen= document.body.offsetHeight/2;
var showOnce = true;
var delay;
function slideUp(){
popUp.style.maxHeight="400px";
popUp.style.padding="10px 20px";
popUp.style.opacity="1";
if(popUp.className==="closed"){
popUp.className="";
}
}
function slideDown(){
popUp.style.maxHeight="0";
popUp.style.padding="0 20px";
popUp.style.opacity="0";
// add class closed for cache
if(popUp.className===""){
popUp.className="closed";
localStorage.setItem('closed', 'true'); //store state in localStorage
}
}
// start interval
function startDelay() {
delay = setInterval(slideUp, 1000);
}
// clear interval
function clearDelay() {
window.clearTimeout(delay);
}
// check if cache heve class close
window.onload = function() {
var closed = localStorage.getItem('closed');
if(closed === 'true'){
popUp.className="closed";
}
}
// show popup when scroll 50%
window.onscroll = function scroll(ev) {
// first time visited
if ((window.innerHeight+window.scrollY) >= halfScreen && showOnce) {
slideUp();
showOnce = false;
}
//same user mutilple time visited the site
else if((popUp.className==="closed" && window.innerHeight+window.scrollY) >= halfScreen && showOnce ){
startDelay();
showOnce = false;
}
};
// close button when click close
for(var i = 0; i<closePopUp.length; i++){
closePopUp[i].addEventListener('click', function(event) {
slideDown();
});
}
my interval didnt work onthe second argument its fire when i refresh, i dont know why.
but if add startDelay on my first arguments its work. but i need to place the interval on my second argu
When you want to make delay use setTimeout function.
Here is documentation of this function.
setInterval Repeatedly calls a function or executes a code snippet, with a fixed time delay between each call.

How to pause and resume jquery interval

I have made a custom slider with jQuery. For this I have used setInterval function:
timer = setInterval(function() {}, 8000);
But I cannot pause and resume the interval. I have 2 buttons (play, pause) which I want to use for. Lets say I click pause after 3 sec, and then resume it. So it should stay in that slider for 5 more seconds and then go to the next one and continue 8 seconds each. I have seen this kinda slider with mouseover pause, but can't do it by myself. I have tried this:
clearInterval(timer);
But this seems reset the interval, don't pause. Can anyone help :)
I'm not entirely sure that's something native to jQuery, however, you could use a flag to pause it, and check in your setInterval whether to execute.
Edit:
Found something that might be useful to you, the jquery-timer
Alternitively, you can keep track of the id set by setInterval, and clear out out when you'd like to pause. Then you can set it again when you wish to resume:
var id = window.setInterval(<code>); //create
window.clearInterval(id); //pause
id = window.setInterval(<code>); //resume
there are two ways of accomplish this:
Clearing the interval everytime you pause and starting a new interval when you resume it.
Having a flag to tell the function in the interval when it is paused and it should not do anything.
The first solution would work like this:
let intervalId = false;
const intervalLength = 8000; // 8 seconds
function intervalFunction () {
// do stuff.
}
startButton.onclick = function () {
if (intervalId === false) {
intervalId = setInterval(intervalFunction, intervalLength);
}
}
pauseButton.onclick = function () {
if (intervalId !== false) {
clearInterval(intervalId);
intervalId = false;
}
}
// auto start it:
intervalId = setInterval(intervalFunction, intervalLength);
The second solution would work like this:
var isRunning = true;
var interval = setInterval(function() {
if (!isRunning) {
// not running, do nothing
} else {
// it is running, do stuff.
}
}, 8000);
pauseButton.onclick = function () {
isRunning = false;
};
startButton.onclick = function () {
isRunning = true;
};
I am not complete sure, that what you are asking for, is the right thing you are showing us... setInterval basically is pure native javascript and in my opinion not worth using! If you wan't to set your timeouts via jquery try this link: http://jchavannes.com/jquery-timer. You can find usages there...
Now on to your problem... you need a state to check wether the slider has to slide or not... simply set a bool like this...
var timer;
var doSlide = false;
var i = 0;
function Slide(){
timer = setTimeout(function(){
if(doSlide == true){
Slide();
i++; // Same as i = i + 1
console.log('Sliding');
if(i == 3) AbortSlide(); /* Abort on third slide! Dont use this in your logic!*/
} else if(doSlide == false){
console.log('Sliding aborted untill next RunSlide() call!')
clearTimeout(timer);
}
},1000);
}
function AbortSlide(){
doSlide = false;
i = 0; // Resetting the count! Dont use this in your logic!
}
function RunSlide(){
doSlide = true;
Slide();
}
RunSlide();
You could also empty the interval in the abort method:
function AbortSlide(){
doSlide = false;
clearTimeout(timer);
i = 0; // Resetting the count! Dont use this in your logic!
}
Here is a working fiddle i made for you to understand what timers and intervals are for: https://jsfiddle.net/q5qzmv68/7/
Hope this helps! Cheers!

window.clearInterval is not working?

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);
}
}

Categories

Resources