mercredi 5 août 2015

Hover to clear and reset Interval for jQuery slideshow


I'm making a simple jQuery slideshow, and have it working except for one thing- I'd like to pause on hover and restart on mouseleave.
I've tried the .hover method as well as .mouseenter + .mouseleave methods, and consistently find that it works correctly for one repetition, but on the second attempt exhibits all kinds of wacky behavior- the mouseenter behavior may not fire, and on mouseleave the timing is completely broken. With a few versions, the slideshow has also gotten stuck between two images, rather than going through all of the images in the set. Here's a codepen with the whole code including HTML and CSS, and I'll post just the js here - the problematic hover code is at the bottom.

  $('#thinger').ready(function() {

  //index images and figure captions with dog class
  $('#thinger img.dog').each(function(idx) {
    $(this).attr('img-index', idx);
    dog_max = idx;
  });
  $("#thinger figcaption.dog").each(function(idx) {
    $(this).attr("figcap-index", idx);
  });

  //index images and figure captions with cat class
  $('#thinger img.cat').each(function(idx) {
    $(this).attr('img-index', idx);
    cat_max = idx;
  });
  $("#thinger figcaption.cat").each(function(idx) {
      $(this).attr("figcap-index", idx);
    });

  //set image height to 70% of window height
  $('#thinger img').css('height', ($(window).innerHeight() * 0.7));

  //vertically centers images if they have a height smaller than the size of the containing figure
  var vertical_center = function(img) {
  var displayHeight = $('#thinger').innerHeight();
  if (displayHeight > img.outerHeight()) {
      img.css({'margin-bottom': (displayHeight - img.outerHeight()) / 2});
    } else {
      img.css({
        'margin-top': ''
      });
    }
  };
  //Resets image size and vertical center when window is resized
  $(window).resize(function() {
    $('#thinger img').css('height', ($(window).innerHeight() * 0.7));
    vertical_center($('#thinger img'));
  });

  do_next_image(1);

  //set interval to advance
  pic_interval = setInterval(do_next_image, 5000);
  });
  //when spans with attribute of "control" are clicked, run the advance script, passing in the +1 or -1 value
  $('span[control]').on('click', function() {
  do_next_image(parseInt($(this).attr('control')));
  //Clear the interval so the viewer has time to see the new image
  clearInterval(pic_interval);
  //reset the interval and run the advance script
  pic_interval = setInterval(do_next_image, 5000);
  })

  var pic_interval;
  var current_index = 0;
  var max_index;

  function do_next_image(iter) {
  //use appropriate max value
  if ($("#dogButton").hasClass("active")) {
    max_index = dog_max;
  } else if ($("#catButton").hasClass("active")) {
    max_index = cat_max;
  }
  //If no value is passed in for iter, assume increase by one
  if (iter === undefined) {
    iter = 1;
  }
  //give var prev the value of the LAST current_index before it gets increased in the next step
  var prev = current_index;

  //increase current_index by iter which will have a -1 effect if iter is negative
  current_index += iter;
  //if  the rotation is at the end, start back at the beginning
  if (current_index > max_index) {
    current_index = 0;
  }
  //if current_index has a value below 0, give it a meaningful value
  else if (current_index < 0) {
    current_index = max_index + 1 + iter;
  }

  function switch_image() {
  //find the image and figure caption with the index prev and change its display to block
  $("img.active[img-index='" + prev + "']").css("display", "block");
  $("figcaption.active[img-index='" + prev + "']").css("display", "block");

  //find the image and figure caption with the index prev and fade them out
    $('img.active[img-index="' + prev + '"]').animate(
      {opacity: 0}, 1000);
    $("figcaption.active[figcap-index='" + prev + "']").animate(
      {opacity: 0}, 1000);

    //Change new image from no display to block
    $('img.active[img-index="' + current_index + '"]').css("display", "block");
    $("figcaption.active[figcap-index='" + current_index + "']").css("display", "block");

    //Change previous image from block display to none
    $('img.active[img-index="' + prev + '"]').css("display", "none");
    $("figcaption.active[figcap-index='" + prev + "']").css("display", "none");

    //find the image that corresponds with current_index and fade in
    $('img.active[img-index="' + current_index + '"]').animate(
      {opacity: 1}, 800);
    $("figcaption.active[figcap-index='" + current_index + "']").animate(
      {opacity: 1}, 800);
  }

  //switch image sets on button click
  $("#dogButton").click(function() {
    //stop previous animation
    $("img, figcaption").stop(true, true).fadeOut("slow");
    //remove previous image
    $("img, figcaption").css("display", "none");
    clearInterval(pic_interval);
    //remove active class from all elements
    $("img, figcaption, button").removeClass("active");
    //add active class to appropriate elements
    $(".dog , #dogButton").addClass("active");
    //run switch_image steps  
    switch_image();
    //reset interval
    pic_interval = setInterval(do_next_image, 5000);
  })

  $("#catButton").click(function() {
    $("img, figcaption").stop(true, true).fadeOut("slow");
    $("img, figcaption").css("display", "none");
    clearInterval(pic_interval);
    $("img, figcaption, button").removeClass("active");
    $(".cat, #catButton").addClass("active");
    switch_image();
    pic_interval = setInterval(do_next_image, 5000);
  })
  switch_image();

//This is the hover pause part that's behaving strangely!

$("#thinger img").mouseenter(function(){
  clearInterval(pic_interval);
  $("#thinger").stop();
});
$("#thinger img").mouseleave(function(){
  pic_interval = setInterval(do_next_image, 5000);
  switch_image();
});
}



via Chebli Mohamed

Aucun commentaire:

Enregistrer un commentaire