如何计算另一个元素上滚动速度的乘数,使它们同时到达终点(视图顶部)

How to calculate the multiplication factor for scroll speed on another element so that they both reach end at the same time (top of view)

本文关键字:顶部 视图 终点 另一个 计算 何计算 元素 速度 滚动      更新时间:2024-02-16

我试图让侧边栏滚动的速度比文章的主要内容慢,这样它在视图中停留的时间就会更长。当元素到达屏幕顶部时,它将锁定。

我见过类似的方法,但它们通常基于固定位置的元素。

请参阅底部的JSFiddle示例,了解它的行为。

HTML

</div>
<div class="container">
  <div class="main">
    Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor
    in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
  </div>
  <div class="sidebar">
    1
    <br />2
    <br />3
    <br />4
    <br />5
    <br />6
    <br />7
    <br />9
    <br />10
    <br />1
    <br />2
    <br />3
    <br />4
    <br />5
    <br />6
    <br />7
    <br />9
    <br />10
    <br />
    <br />4
    <br />5
    <br />6
    <br />7
    <br />9
    <br />10
    <br />
    <div class="data">
      0
    </div>
    <br /> END
  </div>
</div>
<div class="footer">
</div>

CSS

.header {
  width: 100%;
  min-height: 300px;
}
.container {
  margin: 0 auto;
  width: 80%;
  overflow:hidden;
  background-color: #FF00FF;
  display: block;
}
.main {
  width: 65%;
  float: left;
  min-height: 800px;
  background-color: #00ff00;
}
.sidebar {
  width: 30%;
  float: right;
  min-height: 400px;
  background-color: #ff0000;
}
.container.fixed .sidebar {}
.footer {
  clear: both;
  min-height: 2000px;
  width: 100%;
}

JS

  $(document).ready(function() {
    $(window).scroll(function() {
      var sb = $('.sidebar');
      var mn = $('.main');
      var cn = $('.container');
      var height = $(window).height();
      var mnStart = mn.offset().top;
      var mnHeight = mn.height();
      var sbHeight = sb.height();
      var sbLock = cn.height() - sb.height();
      var scrolled = $(window).scrollTop();
      var sbScroll = -(scrolled - mnStart) * ((height - mnHeight) / (height - sbHeight));
      if (scrolled >= mnStart && sbScroll <= sbLock) {
        sb.css({
          transform: 'translate3d(0,' + sbScroll + 'px,0'
        });
      } else if (scrolled < mnStart){
        sb.css({
          transform: 'translate3d(0,' + 0 + 'px,0'
        });
      } else if (sbScroll > sbLock){
        sb.css({
          transform: 'translate3d(0,' + sbLock + 'px,0'
        });         
      }
    });
  });

如果你看一下这个fiddle JSFiddle(简短的主要内容),并将其与这个JSFiddleJSFiddl(长篇主要内容)进行比较,你会发现,随着主要内容长度的变化,脚本并不能很好地工作。

我正在想办法计算我需要的乘法因子,以便使侧边栏平滑滚动,直到它到达与主要内容相同的底部位置。正如您在示例1中看到的。

我能得到的最好的结果是:

$(window).scroll(function(e){
parallax();
});
function parallax(){
var scrolled = $(window).scrollTop();
$('.main').css('top',-(scrolled*0.1)+'px');
$('.sidebar').css('top',-(scrolled*0.2)+'px');
}

请记住,这是一种非常简单的方法,但侧边栏在视图中停留的时间更长,您可以摆弄函数参数,看看会发生什么,是的,固定css位置,否则将不起作用。这需要一些css规则才能看起来整洁,但JS功能是有效的。

http://codepen.io/damianocel/pen/NNwmRm

另一种选择是在边带上设置一个计时器,让它在给定的时间和滚动位置后淡入淡出或变换,比如这里:

http://codepen.io/damianocel/pen/PZQVOR

从头开始重新做这方面的工作,并找到了符合我需求的解决方案。

我想也许其他人会好好利用它。

HTML

<div class="header">
</div>
<div class="container">
  <div class="main">
    Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor
    in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
  </div>
  <div class="sidebar">
    1
    <br />2
    <br />3
    <br />4
    <br />5
    <br />6
    <br />7
    <br />8
    <br />9
    <br />10
    <br />11
    <br />12
    <br />13
    <br />14
    <br />15
    <br />16
    <br />17
    <br />18
    <br />19
    <br />20
    <br />21
    <br />22
    <br />23
    <br />24
    <br />25
    <br />26
    <br />27
    <br />28
    <br />29
    <br />END
  </div>
</div>
<div class="footer">
</div>
</div>

CSS

.header {
  width: 100%;
  min-height: 300px;
}
.container {
  margin: 0 auto;
  width: 80%;
  overflow: hidden;
  background-color: #FF00FF;
  display: block;
}
.main {
  width: 65%;
  float: left;
  min-height: 8000px;
  background-color: #00ff00;
}
.sidebar {
  width: 30%;
  float: right;
  min-height: 400px;
  background-color: #ff0000;
}
.container.fixed .sidebar {}
.footer {
  clear: both;
  min-height: 2000px;
  width: 100%;
}

JS

  $(document).ready(function() {
    $(window).scroll(function() {
        slowScroll('.main','.sidebar');
    });
    function slowScroll(obj1, obj2) {
      var long, short;
      if ($(obj1).height() > $(obj2).height()) {
        long = $(obj1);
        short = $(obj2);
      } else {
        long = $(obj2);
        short = $(obj1);
      }
      var lHeight   = long.height(); // Height of longest element
      var sHeight   = short.height(); // Height of shortest element
      var sLock     = lHeight - sHeight; // What position from top the shortest element should lock in at
      var startPos  = long.offset().top; // The start position relevant to document (offset from top)
      var scrolled  = $(window).scrollTop(); // Current value scrolled from top
      var lScrolled = ((scrolled - startPos) >= 0) ? (scrolled - startPos) : 0;// Current value scrolled from start of longest element
      var scrollX   = sLock/lHeight; // Scroll multiplier
      var sPos  = ((lScrolled * scrollX) <= sLock) ? (lScrolled * scrollX) : sLock;// Scroll position for the shortest element
      short.css({transform: 'translate3d(0,' + sPos + 'px,0'});
    }
});

到目前为止,我已经测试了它,它似乎可以处理主元素和侧边栏元素的不同高度,正如您在这里的JSFiddle中看到的那样。