【问题标题】:jQuery offset().top slightly off every other timejQuery offset().top 每隔一段时间稍微偏离一次
【发布时间】:2015-06-16 18:41:24
【问题描述】:

我正在尝试让父 div 的内部按设定的时间间隔滚动到下一个子 div。但是,滚动只工作了一半,我不知道为什么。它应该滚动浏览所有 8 个孩子,但只浏览了大约一半。

在我制作的这个 jsfiddle 中,偏移量每隔一次只有 1px,而它应该是 ~250px。在我的实际代码中,它关闭了 0px,而它应该关闭了 ~250px。

https://jsfiddle.net/rLeLogx0/3/

这是 JS:

//scroll to 2nd one first
var index = 1;

setInterval(function(){
    var parent = $('.parent');
    var children = parent.find('.child');
    var target = children.eq(index);   
    var offset = target.offset().top - $('.parent').offset().top;

    //ISSUE: outputs the "same" value every other time
    console.log(target.offset().top);

    parent.animate({
        scrollTop: offset
    }, 200);
    index = (index+1) % children.length;
}, 1000);

【问题讨论】:

    标签: javascript jquery html css


    【解决方案1】:

    试试这个计算偏移量:

    var offset = target.position().top + parent.scrollTop();
    

    更新 jsfiddle:https://jsfiddle.net/rLeLogx0/21/

    更新:

    如果您确实希望您的 offset 变量包含偏移量,您可以在您的 .animate() 中增加 scrollTop 参数中的值

    var target = children.eq(index);
    
    [...]
    
    parent.animate({
        scrollTop: '+='+offset
    }, 200);
    

    见 jsfiddle:https://jsfiddle.net/rLeLogx0/23/

    【讨论】:

    • 太完美了!谢谢!
    【解决方案2】:

    尝试运行position().top 而不是offset.top()

    difference

    【讨论】:

    • 我尝试用位置替换偏移量,但没有帮助。 jsfiddle.net/rLeLogx0/17。也许我需要改变更多。
    • 原来我必须使用位置。 @Prusprus 提供了上面的解决方案。
    【解决方案3】:

    这样的?

    $(document).ready(function() {
      var child = $('.parent .child'), index = 0;
    
      var scrollIt = function() {
        var top = child.eq(index).offset().top;
        
        index++;
    
        if (index >= child.length) {
          index = 0;
        }
    
        setTimeout(function() {
          scrollIt();
        }, 1000);
    
        $('html, body').animate({ scrollTop: top });
      }
      
      scrollIt();
    });
    .parent {
      display: block;
      width: 100%;
    }
    
    .child {
      display: block;
      width: 100%;
      height: 96px;
      background: #ccc;
      margin-bottom: 10px;
    }
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    
    <div class="parent">
      <div class="child">1</div>
      <div class="child">2</div>
      <div class="child">3</div>  
      <div class="child">4</div>
      <div class="child">5</div>
      <div class="child">6</div>
      <div class="child">7</div>
    </div>

    【讨论】:

      【解决方案4】:

      您的问题是offset 给您从父级顶部到下一个目标的距离,因为子级顶部值一直在更新,但设置scrollTop 是绝对距离,而不是偏移量.这是您应该使用的代码:

      //scroll to 2nd one first
      var index = 1;
      
      setInterval(function(){
          var parent = $('.parent');
          var children = parent.find('.child');
          var target = children.eq(index);   
          var offset = target.offset().top - $('.parent').offset().top;
      
          //outputs the same value every other time
          console.log(target.offset().top);
      
          var newScroll = parent.scrollTop() + offset;
      
          parent.animate({
              scrollTop: newScroll
          }, 200);
          index = (index+1) % children.length;
      }, 1000);
      

      JsFiddle:https://jsfiddle.net/mvs6Ltgu/

      【讨论】: