jQuery - Image replacement transition [issues in Safari]

时间:2016-04-07 10:33:21

标签: javascript jquery

Okay I have the following code:-

[SEE JSFIDDLE]

HTML:

<div id="header">
    <span class="mobile-menu"></span>
</div>

CSS:

#header {
  width: 100%;
  background: #000000;
  height: 100px;
}

.mobile-menu {
    position: absolute;
    right: 25px;
    top: 20px;
    background: url(http://planetbounce.m360.co.uk/wp-content/themes/planetbounce/assets/img/buttons/menu-01.png);
    background-repeat: no-repeat;
    background-size: 26px !important;
    height: 26px;
    width: 26px;
    display: inline-block;
    margin: 7px 0;
    -webkit-transition-duration: 0.8s;
    -moz-transition-duration: 0.8s;
    -o-transition-duration: 0.8s;
    transition-duration: 0.8s;
}

.mobile-menu-hover {
    background: url(http://planetbounce.m360.co.uk/wp-content/themes/planetbounce/assets/img/mobile-menu-hover.png);
}

jQuery:

var imagesArray = ["http://planetbounce.m360.co.uk/wp-content/themes/planetbounce/assets/img/buttons/menu-01.png",
                   "http://planetbounce.m360.co.uk/wp-content/themes/planetbounce/assets/img/buttons/menu-02.png",
                   "http://planetbounce.m360.co.uk/wp-content/themes/planetbounce/assets/img/buttons/menu-03.png",
                   "http://planetbounce.m360.co.uk/wp-content/themes/planetbounce/assets/img/buttons/menu-04.png",
                   "http://planetbounce.m360.co.uk/wp-content/themes/planetbounce/assets/img/buttons/menu-05.png",
                   "http://planetbounce.m360.co.uk/wp-content/themes/planetbounce/assets/img/buttons/menu-06.png",
                   "http://planetbounce.m360.co.uk/wp-content/themes/planetbounce/assets/img/buttons/menu-07.png"];

function preloadImg(pictureUrls, callback) {
  var i, j, loaded = 0;
  var imagesArray = [];

  for (i = 0, j = pictureUrls.length; i < j; i++) {
    imagesArray.push(new Image());
  }
  for (i = 0, j = pictureUrls.length; i < j; i++) {
    (function (img, src) {
      img.onload = function () {
        if (++loaded == pictureUrls.length && callback) {
          callback(imagesArray);
        }
      };
      img.src = src;
    }(imagesArray[i], pictureUrls[i]));
  }
};


function changeImage(background, imagesArray, index, reverse) {
  background.css("background-image", "url('" + imagesArray[index].src + "')").fadeIn(10, function() {
    if (reverse) {
      index--;
      if (index == -1) {
        return; // stop the interval
      }
    } else {
      index++;
      if (index == imagesArray.length) {
        return; // stop the interval
      }
    }
    //Fade in the top element
    background.fadeOut(10, function () {
      //Set the background of the top element to the new background
      background.css("background-image", "url('" + imagesArray[index] + "')");
      changeImage(background, imagesArray, index, reverse);
    });
  });
}



jQuery(function () {
  /* Preload Image */
  preloadImg(imagesArray, function (imagesArray) {
    jQuery(".mobile-menu").css("background-image", "url('" + imagesArray[0].src + "')")
    jQuery('.mobile-menu').on('click', {imgs: imagesArray}, function (event) {
      var background = jQuery(".mobile-menu");
      var bi = background.css('background-image');
      var index = 0;
      var reverse = false;
      if (imagesArray[0].src != bi.replace('url("', '').replace('")', '')) {
        index = imagesArray.length - 1;
        reverse = true;
      }
      changeImage(background, event.data.imgs, index, reverse);
    });
  });
});

The Issue:

This works fine in Firefox and Chrome, it transitions between the 7 different images on click, then does the reverse on the second click (toggling).

The problem is when I try this in Safari, it basically goes through the image replacement process then reverts back to the first image for some reason and I can't figure out why?

Any ideas?

1 个答案:

答案 0 :(得分:1)

It seems to be because Safari returns the background-image without double quotes, but your replace function checks for url(", so it doesn't replace and reverse never gets true.

Instead of replacing you can check using either indexOf or matching using a RegExp, it would be safer and more straightforward. Either:

if ( bi.indexOf(imagesArray[0].src) == -1) {

or

 if (imagesArray[0].src != bi.match(/http.+png/)[0]) {

With indexOf: http://jsfiddle.net/u9ske14r/