视差滚动–降低容器的高度以匹配变换间隙

Joh*_*ter 8 javascript jquery parallax

我在页面上安排了元素的位置–通过CMS控制的位置,该控件为每个元素提供了宽度,顶部位置,左侧位置,z索引和“速度”。

该速度用于使用JS创建视差效果。它取“速度”,并用window.pageYOffset– 计算。如果速度小于0,则将window.pageYOffset速度除以速度;如果速度大于0 window.pageYOffset,则将速度乘以速度。在滚动时,它会调整Y平移以产生这种“视差”效果。

通常,这一切都很好,但是当您更改滚动元素的Y位置时,您会在底部留下一个“间隙”(如果滚动速度与用户滚动速度匹配,元素将位于此处)。

为了纠正这一点,我想我会获得最底部的元素,并获得其getBoundingClientRect().bottom位置并在滚动时减小容器的高度以匹配该元素的底部,因此当您向下滚动或向上滚动时,容器会收缩/展开以匹配,从而消除差距。

但是,这似乎不起作用。数学/逻辑错误或者我错过了整件事。

下面是我的代码,我建立了一个JSFiddle来帮助可视化。

https://jsfiddle.net/6up3vqjn/2/

// Runs on init and resize
function parallaxInit() {

  var $container = $('.parallax'),
    container = $container[0];

  var testArray = [],
    $testLastElement;

  $('.parallax > .group').each(function() {

    var $group = $(this),
      group = $group[0],
      groupBounds = group.getBoundingClientRect(),
      $lastElement,
      lastElementBoundsBottom = 0;

    $group.find('> div').each(function() {

      var $div = $(this),
        div = $div[0],
        initTop = $div.attr('data-top');

      if (initTop == 0) {
        $div.css('top', '0');
      } else {
        $div.css('top', $(window).width() / 12 * initTop - 26 + 'px');
      };

      group.removeAttribute('style');
      $group.height(group.scrollHeight).attr('data-height', group.scrollHeight);

      var divBounds = div.getBoundingClientRect();
      testArray.push(divBounds.bottom);

    });

  });

  $('.parallax > .group > div').each(function() {

    var divBottomBounds = $(this)[0].getBoundingClientRect().bottom;

    if (divBottomBounds == Math.max.apply(Math, testArray)) {
      $testLastElement = $(this);
      $(this).addClass('is--last');
    }

    var letters = "0123456789ABCDEF";
    var color = '#';
    for (var i = 0; i < 6; i++) color += letters[(Math.floor(Math.random() * 16))];
    $(this).css('background-color', color);


  });

  $container[0].style.height = $testLastElement[0].getBoundingClientRect().bottom + 'px';

}
parallaxInit();
$(window).on('resize', parallaxInit);

// Runs on scroll
function parallax() {

  var $container = $('.parallax');

  var test = 0;
  var testArray = [],
    $testLastElement;

  $('.parallax > .group').each(function() {

    var $group = $(this),
      group = $group[0],
      groupHeight = $group.attr('data-height'),
      groupBounds = group.getBoundingClientRect();

    $group.find('> div').each(function() {

      var $this = $(this),
        speed = $this.attr('data-speed');

      if (speed < 0) {
        speed = Math.abs(speed);
        var yPos = window.pageYOffset / speed;
      } else {
        var yPos = window.pageYOffset * speed;
      }
      yPos = -yPos;

      $this[0].style.transform = "translate3d(0, " + yPos + "px, 0)";

      var divBounds = $this[0].getBoundingClientRect(),
        divRelativeBounds = {};

      testArray.push(divBounds.bottom);

    });

  });


  $('.parallax > .group > div').each(function() {

    var divBottomBounds = $(this)[0].getBoundingClientRect().bottom;
    $(this).removeClass('is--last');

    if (divBottomBounds == Math.max.apply(Math, testArray)) {
      $testLastElement = $(this);
      $(this).addClass('is--last');
    }

  });

  $container[0].style.height = $testLastElement[0].getBoundingClientRect().bottom + 'px';

}
$(window).bind('scroll', parallax);
Run Code Online (Sandbox Code Playgroud)

更新了JSFiddle,删除了容器高度计算:https ://jsfiddle.net/ejqhvz2c/

Dec*_*erz 2

我不是 100% 这正是你所追求的,但我已经停止了过度滚动和滚动到空白区域。首先我改变了事件的触发方式。由于它是一个视差,我将其绑定到滚轮事件而不是实际滚动,当页面上实际有内容时,这实际上并不重要。然后我使用了一个名为的全局变量paralaxYOffset,我决定最好以 +- 50 间隔递增以实现平滑度并停止过度滚动,我添加了一个检查以查看.is--lasty 位置是否 <= 0,然后不允许视差进一步滚动。

活动变更:

if(e.originalEvent.deltaY  > 0){
        if($(".is--last")[0].getBoundingClientRect().y > 0){
            window.paralaxYOffset += 50;
      }
  }else{
    window.paralaxYOffset -= 50;
  }

  if(window.paralaxYOffset < 0)
    window.paralaxYOffset = 0;
Run Code Online (Sandbox Code Playgroud)

为了确保一切看起来正确并删除溢出滚动条,我将其.parallax设置100vhoverflow: hidden

我相信这可以达到您的要求:)

https://jsfiddle.net/fynmtk9b/4/