Skip to content

A question regarding jQuery hover(), setInterval scope, and The “this” Problem —

UPDATE — from CertainPerformance:

$(".gallery-image").each(function() {
  let callInterval;
  $(this).hover(function(){
    clearInterval(callInterval);
  }, function(){
    callInterval = setInterval(intervalFunction.bind(this), 500);   
  });
});

This helped with the scope question; but now I have a follow up –

Each image at position i needs to be iterating over a separate index, index which determines the current src of the image at position i. The starting index for each image’s setInterval loop should be its position and then index++ each loop. But I’m stuck where each image’s src index is only incrementing by one, and then reiterating that same value for each setInterval loop. Where the heck am I supposed to be declaring the index so that it’s local to each image’s setInterval loop but is incremented without being reset at its starting value….?

This is so elementary, but I can’t just get it all together.

—————–

Before I start — I’ve spent a few hours going through SO questions that address certain parts of this, but I’m getting really stuck putting it all together, so forgive me if this a duplicate of several things, ha.

I’m making an image gallery page, where the placeholder for each image rapidly cycles through all possible gallery images until user hovers over that image/placeholder, upon which the “proper” image is (statically) displayed. Then when the user hovers out, that image resumes its rapid cycling. Each image placeholder is cycling through sources simultaneously & independently of each other.

I’m having trouble with needing both hover-in and hover-out parts of the jQuery hover() function to reference the same setInterval ID, but at the same time, the setInterval should have a local scope, specific to each image element being hovered over. I’m also somewhat new to jQuery, and the distinctions between it and js at large aren’t always super clear to me.

HTML:

<div class="gallery">
    <img class="gallery-image" src="image0.jpg">
    <img class="gallery-image" src="image1.jpg">
    <img class="gallery-image" src="image2.jpg">
    <img class="gallery-image" src="image3.jpg">
    <img class="gallery-image" src="image4.jpg">
</div>

js:

var images = document.getElementsByClassName('gallery-image');
var callInterval;
    
$(".gallery-image").hover(function(){
        clearInterval(callInterval);
    }, function(){
        callInterval = setInterval(intervalFunction.bind(this), 500);   
    })

function intervalFunction(){
    var position = $(this).index();     
    var index = position;
    if (index < 14) {
        $(this).attr("src", "image" + index + ".jpg");
        index++;                    
    } else {
        $(this).attr("src", "image" + index + ".jpg");
        index = 0;
    }
}

I’ve tried both vanilla javascript and jQuery, as well as various combinations of the two. Am I mixing them in the wrong way? Do I need multiple hover() functions, and define the setInterval functions that way? Should I just manually write out a hover() for each image in the gallery and tie the setInterval functions to each image that way?

Would it be more helpful to post a snippet?

I feel like I’ve just been staring at this problem for so long that I’m just getting in my own way now, the answer’s got to be right in front of me… I’m losing my mind ha.

Answer

I’d iterate over each element with each, creating a new local scope for each that the callInterval can be declared in:

$(".gallery-image").each(function() {
  let callInterval;
  $(this).hover(function(){
    clearInterval(callInterval);
  }, function(){
    callInterval = setInterval(intervalFunction.bind(this), 500);   
  });
});