Search code examples
javascriptjqueryfirefoxparallax

Firefox loads parallax image size wrong (only on refresh)


I have an odd bug in the current Firefox. I'm running a parallax script (I think it comes from Materialize), this is the source:

(function($) {
  $.fn.parallax = function() {
    var window_width = $(window).width();

    return this.each(function(i) {
      var $this = $(this);
      $this.addClass('parallax');

      $this.find('img').each(function() {
        $(this).css('background-image', 'url(' + $(this).prop('currentSrc') + ')');
        $(this).attr('src', 'data:image/gif;base64,R0lGODlhAQABAIABAP///wAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==');
        $(this).attr('srcset', '');
      });

      function updateParallax(initial) {
        var container_height;
        // if (window_width < 992) {
        container_height = ($this.height() > 0) ? $this.height() : $this.children("img").height();
        // }
        // else {
        // container_height = ($this.height() > 0) ? $this.height() : 500;
        // }
        var img_height = $this.children("img").height();
        var parallax_dist = img_height - container_height;
        var bottom = $this.offset().top + container_height;
        var top = $this.offset().top;
        var scrollTop = $(window).scrollTop();
        var windowHeight = window.innerHeight;
        var windowBottom = scrollTop + windowHeight;
        var percentScrolled = (windowBottom - bottom) / (container_height + windowHeight);
        var parallax = -1 * parallax_dist * percentScrolled;

        console.log(
          'img_height: ' + img_height + '\n' +
          'parallax_dist: ' + parallax_dist + '\n' +
          'bottom: ' + bottom + '\n' +
          'top: ' + top + '\n' +
          'scrollTop: ' + scrollTop + '\n' +
          'windowHeight: ' + windowHeight + '\n' +
          'windowBottom: ' + windowBottom + '\n' +
          'percentScrolled: ' + percentScrolled + '\n' +
          'parallax: ' + parallax + '\n'
        );

        if ((bottom > scrollTop) && (top < (scrollTop + windowHeight))) {
          $this.children("img").first().css('bottom', parallax + "px");
        }
        if (initial) {
          $this.children("img").first().css('display', 'block');
        }
      }

      // Wait for image load
      $this.children("img").one("load", function() {
        updateParallax(true);
      }).each(function() {
        if (this.complete) $(this).load();
      });

      $(window).scroll(function() {
        window_width = $(window).width();
        updateParallax(false);
      });

      $(window).resize(function() {
        window_width = $(window).width();
        updateParallax(false);
      });

    });

  };
}(jQuery));
.parallax-container {
  position: relative;
  overflow: hidden;
  height: 500px;
}
.parallax {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: -1;
}
.parallax img {
  display: none;
  position: absolute;
  bottom: 0;
  width: 100%;
  max-width: 100%;
  min-height: 100%;
  background-position: bottom;
  background-size: contain;
  background-repeat: no-repeat;
}
<div class="full-parallax parallax-container">
  <div class="parallax">
    <img src="http://lorempixel.com/1000/1000/" srcset="http://lorempixel.com/1000/1000/ 2000w, http://lorempixel.com/500/500/ 500w" alt="">
  </div>
</div>

<div class="content">
  <h1>Hello!</h1>
  <p>Text text text text text text</p>
  <p>Text text text text text text</p>
  <p>Text text text text text text</p>
  <p>Text text text text text text</p>
  <p>Text text text text text text</p>
  <p>Text text text text text text</p>
  <p>Text text text text text text</p>
  <p>Text text text text text text</p>
  <p>Text text text text text text</p>
  <p>Text text text text text text</p>
  <p>Text text text text text text</p>
  <p>Text text text text text text</p>
  <p>Text text text text text text</p>
  <p>Text text text text text text</p>
  <p>Text text text text text text</p>
  <p>Text text text text text text</p>
  <p>Text text text text text text</p>
  <p>Text text text text text text</p>
  <p>Text text text text text text</p>
  <p>Text text text text text text</p>
  <p>Text text text text text text</p>
  <p>Text text text text text text</p>
</div>



<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>

<script>
  $(document).ready(function() {
    $('.parallax').parallax();
  });
</script>

This works all fine, BUT in Firefox this only works if I load the page for the first time (or reload with deleting cache). If I reload the page normally (F5), the parallax does not load properly, (image is way to far up) until I scroll for the first, then the image jumps right into place.

The issue seems to be that FF loads the image size wrong. On reload without cache it reads the image height for the same image with 1707 and on normal reload with cache it reads 678. As soon as I start to scroll that value jumps up to 1707 though.

edit: it also only happens if the page is scrolled to the absolute top, if I scroll down 1px it loads the image correctly.

Chrome and Vivaldi do this well.


Solution

  • This most certainly seems to be a FF bug (https://bugzilla.mozilla.org/show_bug.cgi?id=1281438)