1

I have a carousel plugin I've created and I need a way to have it run a function that moves the image to the side and brings in the next image. I have this working with navigation arrows but I want to implement a way for it to do this on its own.

I'm having trouble finding information on this as Google is bloated with everyone's carousel libraries.

Basically, I just need something like:

window.setTimeout(() => {
  // do something
}, 1000);

But it needs to run over and over unless a particular event is triggered. My first thought was a while loop but that would have been disastrous.

I don't have much to show but currently, this is the code:

  let mouseIsOver = false;

  inner.addEventListener('mouseenter', () => {
    mouseIsOver = true;

    console.log(mouseIsOver);
  });

  inner.addEventListener('mouseleave', () => {
    mouseIsOver = false;

    console.log(mouseIsOver);
  });
Nishant
  • 20,354
  • 18
  • 69
  • 101
Brandon Benefield
  • 1,504
  • 1
  • 21
  • 36

3 Answers3

2

You could use the setInterval method which repeatedly calls a function. And then call clearInterval to stop it.

const inner = document.getElementById('inner');
const pages = ['mediumspringgreen', 'coral', 'cyan', 'moccasin'];
let interval = start();
let i = 0;

function start() {
    return setInterval(() => inner.style.background = pages[i++ % 4], 3000);
}

inner.addEventListener('mouseenter', () => {
  clearInterval(interval);
  console.log('pause');
});

inner.addEventListener('mouseleave', () => {
  interval = start();
  console.log('continue');
});
#inner { width: 100px; height: 100px; background: cyan }
.as-console-wrapper { max-height: 1.5em !important; }
<div id=inner></div>
Kirill Simonov
  • 8,257
  • 3
  • 18
  • 42
  • You need to use requestAnimationFrame because that allows the browser to choose when the next available rendering frame is available. – Geuis Mar 12 '18 at 09:31
  • 1
    @Geuis You're not right. `requestAnimationFrame` is designed to animate elements (for example, repaint something 60 times per second). And `setInterval` executes some action at a fixed rate (which is what OP asks for). Technically, `setInterval` _can_ be used to perform animation and `requestAnimationFrame` _can_ be used to execute some action at a fixed rate, but both of these approaches are bad practice. – Kirill Simonov Mar 13 '18 at 03:13
  • I'm interpreting his question as needing to run the same function over and over to change a CSS property. You shouldn't do this inside of a setTimeout because it prevents the browser from choosing the most efficient time to repaint. – Geuis Mar 13 '18 at 19:04
  • 1
    Thanks , setInterval(() => inner.style.background = pages[i++ % 4], 3000); this snippet helped me resolve my Question. – Amarnath Reddy Surapureddy May 13 '23 at 05:52
1

Basically, I just need something like:

window.setTimeout(() => {
  // do something
}, 1000);

But it needs to run over and over unless a particular event is triggered.

Have you considered window.setInterval()?

The setInterval() method... repeatedly calls a function or executes a code snippet, with a fixed time delay between each call. It returns an interval ID which uniquely identifies the interval, so you can remove it later by calling clearInterval().

Considering your use case, here's one possible solution:

  let mouseIsOver = false;

  // start a timer that runs goToNextImage() every 1000 ms and
  // stores its ID so it can be cancelled on mouseenter
  let goToNextImageTimer = window.setInterval(goToNextImage, 1000);

  inner.addEventListener('mouseenter', () => {
    mouseIsOver = true;

    console.log(mouseIsOver);

    if (goToNextImageTimer !== null) {
      // stop interval timer if running
      window.clearInterval(goToNextImageTimer);
    }
  });

  inner.addEventListener('mouseleave', () => {
    mouseIsOver = false;

    console.log(mouseIsOver);

    if (goToNextImageTimer === null) {
      // start interval timer if not running
      goToNextImageTimer = window.setInterval(goToNextImage, 1000);
    }
  });
ArkaneMoose
  • 111
  • 2
  • 7
0

Need to look at requestAnimationFrame. https://developer.mozilla.org/en-US/docs/Web/API/window/requestAnimationFrame

Geuis
  • 41,122
  • 56
  • 157
  • 219
  • 1
    I wouldn't use `requestAnimationFrame` for a use case like this because it looks like the question asker does not need to (quoting the MDN article) "update an animation before the next repaint," but rather call it every second or so. `setInterval` looks more suited to this use case. If the function being called were actually animating the carousel every frame, then I would recommend `requestAnimationFrame` for that (potentially started by a `setInterval`). – ArkaneMoose Mar 12 '18 at 07:12
  • @ArkaneMoose Any time you are doing any kind of animation with js in the DOM, you need to use requestAnimationFrame. It was specifically designed for this problem space. – Geuis Mar 12 '18 at 09:32
  • 1
    Please care to provide an example of executing some action every 3 seconds using `requestAnimationFrame`. I'm just curious how you implement it. I'm not going to downvote you by the way. – Kirill Simonov Mar 13 '18 at 03:50