Question

I have a site that displays a mosaic of images like so.

enter image description here

When the page loads I store an array of image links in each of the image-div data attribute. So each picture in the mosaic is a div with a background image, and has an array of image links associated with it.

I want to make it so when you hover over an image, it changes the background image for the div every few seconds, but only when the mouse is hovered over the image.

When I hover over any one of the images I run this code

$(@).find('div.item').mouseenter ->
    return if $(@).attr("class") == "item is-expanded"
    enteredDiv = $(this)
    changeImage(enteredDiv)

$(@).find('.item').mouseleave ->
  return if $(@).attr("class") == "item is-expanded"
  clearInterval stopChangeImage

Which calls these functions

x = 0
stopChangeImage = null

changeImage = (enteredDiv) ->
  workImg = enteredDiv.children('.item-content').data('work-img')
  console.log 'attachment url image test ' + workImg[0]
  selectedImg = workImg[x]
  x++
  x = 0  if x >= workImg.length
  if selectedImg
    enteredDiv.children('.item-content').css 'background-image','url(' + selectedImg + ')'
    stopChangeImage = 
      setInterval(->
        changeImage enteredDiv
      , 1000)

But I am getting really buggy results. It starts to flip through the images but it does not stop on mouseleave. Also the interval starts to get really buggy and the timing is not correct. Please help me find a better way to do this! THanks!

Was it helpful?

Solution

You could, every second, find all the expanded item divs that are being hovered over (probably only one) and immediately change their image:

setInterval(function(){
 $('div.item.is-expanded:hover').each(
  function(){changeImage($this);}
 );
},1000);

function changeImage()
{
 [function from your question]
}

OTHER TIPS

I don't wanna get into the code, but let imgDivs be an array of all of the divs (for example, get it calling getElementsByClassName), and let each of those divs contain an array link with the links to the images.

changeImage=function(){
        this.imgId==(this.imgId==this.links.length-1?0:this.imgId+1);
        this.style.backgroundImage="url("+this.links[imgId]+")";
}
imgDivs.forEach(function(imgDiv){
    imgDiv.imgId=0;
    imgDiv.changeImage=changeImage.bind(imgDiv);
    imgDiv.onmouseover=function(){
        this.intId=setInterval(changeImage,1000);
    }
    imgDiv.onmouseleave=function(){
        clearInterval(this.intId);
    }
});

@Teh Walris solution iterates through the divs every second, while my does not.

But does it work?

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top