在可滚动元素上使用时,LocalScroll存在问题

时间:2019-03-22 19:12:32

标签: jquery plugins scroll scrollto

我注意到,如果您将LocalScroll插件与可滚动元素一起使用,并且在这些元素中使用了滚动,则该行为有时看起来像是一个错误。

带有问题示例的URL: http://jsfiddle.net/oms02/s53h7gko/26/

$.localScroll({
    target: '#wrapper',
    axis: 'xy',
		queue:true,
		duration:1000,
		hash:false,
		lazy:true,
    onBefore:function( e, anchor, $target ){
		},
		onAfter:function( anchor, settings ){
		}
});
#wrapper {
  border:3px solid black;
  width:400px;
  height:300px;
  margin: 10px auto 0;
  overflow:hidden;
}

#div1 {
  width:4000px;height:500px;
  overflow-y:auto;overflow-x:auto;
  border:1px solid red;
  margin:5px 0 0 5px;
}

#div2 {
  width:4000px;height:500px;
  overflow-y:auto;overflow-x:auto;
  border:1px solid red;
  margin:5px 0 0 5px;
}

.box {
  float:left;
  border:1px solid green;
  width:200px;height:600px;
}

.box h2 {
  margin:0 auto;
  text-align:center;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="http://demos.flesler.com/jquery/scrollTo/js/jquery.scrollTo-min.js?1.4.11"></script>
<script src="http://demos.flesler.com/jquery/localScroll/js/jquery.localscroll-min.js?1.3.4"></script>
<a href="#section2.1">go to section 2.1</a>
<br>
<a href="#section2.2">go to section 2.2</a>

<div id="wrapper">
  <div id="div1">
    <div class="box" id="section1.1">
      <h2>content 1.1</h2>
    </div>
    <div class="box" id="section1.2">
      <h2>content 1.2</h2>
    </div>
    <div class="box" id="section1.3">
      <h2>content 1.3</h2>
    </div>
    <div class="box" id="section1.4">
      <h2>content 1.4</h2>
    </div>
    <div class="box" id="section1.5">
      <h2>content 1.5</h2>
    </div>
    <div class="box" id="section1.6">
      <h2>content 1.6</h2>
    </div>
  </div>
  <div id="div2">
    <div class="box" id="section2.1">
      <h2>content 2.1</h2>
    </div>
    <div class="box" id="section2.2">
      <h2>content 2.2</h2>
    </div>
    <div class="box" id="section2.3">
      <h2>content 2.3</h2>
    </div>
    <div class="box" id="section2.4">
      <h2>content 2.4</h2>
    </div>
    <div class="box" id="section2.5">
      <h2>content 2.5</h2>
    </div>
    <div class="box" id="section2.6">
      <h2>content 2.6</h2>
    </div>
  </div>
</div>

场景:

有一个包装器(小尺寸),在其内部有两个大的可滚动div(彼此相邻),其中六个浮动元素的高度大于其父级,以便用户可以使用滚动。 在简历中,“地图”如下所示:

| 1.1 | 1.2 | 1.3 | 1.4 | 1.5 | 1.6 |

| 2.1 | 2.2 | 2.3 | 2.4 | 2.5 | 2.6 |

步骤:

  1. 单击链接“转到第2.1节”。正确地将您引至该div。
  2. 滚动该部分,然后单击其他链接,请确保div#section2.1不在顶部(滚动)。在这种情况下,您将无法看到该框的文本。
  3. 单击链接“转到2.2节”:在第二个动作(在y轴上)上滚动整个包装器,这是错误的,因为滚动应该在#div2上进行。框的文本看起来像是隐藏的。如果滚动第2节的框,则会看到其中的内容,但可以看到该插件未将您带到正确的位置。

我几乎尝试了所有方法,但都失败了: 1.在两个元素之间设置边距。 2.在它们之间插入第三个div(相对位置和较低的z-index)。 3.在开始移动之前,将滚动div的位置设置为顶部。

结果始终相同:两个div看起来都像是碰撞/粉碎

有什么主意吗? 预先感谢!

1 个答案:

答案 0 :(得分:0)

  

这些框的文本看起来像是隐藏的。如果滚动第2节的框,则会看到其中的内容,但可以看到该插件并未将您带到正确的位置。

可以使用offset和onAfter回调解决问题:

  • onAfter:仅首次保存每个锚的当前最高位置
  • 偏移量:再次计算当前顶部,如果不同(请参见滚动事件),则返回一个偏移量以进行补偿

为了补偿滚动,您还需要在offset回调中添加对scrollTop动画的调用。

    $.localScroll({
            target: '#wrapper',
            axis: 'xy',
            queue: true,
            duration: 1000,
            hash: false,
            lazy: true,
            offset: function(elem, anchor) {
                var top = anchor.offset().top + $(this.target).scrollTop() - $(this.target).offset().top;
                var startPos = anchor.data('startPos');
                if (startPos != undefined && startPos != top) {
                    startPos = {top: startPos - top, left: 0};
                }
                // in order to compensate the scroll...next line
                anchor.parent().animate({ scrollTop: 0 }, 10)
                return startPos;
            },
            onBefore: function (e, anchor, $target) {
            },
            onAfter: function (anchor, settings) {
                var startPos = anchor.data('startPos');
                if (startPos == undefined) {
                    var self = this;
                    anchor.siblings().addBack().each(function(idx, ele) {
                        var top = anchor.offset().top + $(self).scrollTop() - $(self).offset().top;
                        $(ele).data('startPos', top);
                    });
                }
            }
     });

$.localScroll({
  target: '#wrapper',
  axis: 'xy',
  queue: true,
  duration: 1000,
  hash: false,
  lazy: true,
  offset: function(elem, anchor) {
      var top = anchor.offset().top + $(this.target).scrollTop() - $(this.target).offset().top;
      var startPos = anchor.data('startPos');
      if (startPos != undefined && startPos != top) {
          startPos = {top: startPos - top, left: 0};
      }
      anchor.parent().animate({ scrollTop: 0 }, 10)
      return startPos;
  },
  onBefore: function (e, anchor, $target) {
  },
  onAfter: function (anchor, settings) {
      var startPos = anchor.data('startPos');
      if (startPos == undefined) {
          var self = this;
          anchor.siblings().addBack().each(function(idx, ele) {
              var top = anchor.offset().top + $(self).scrollTop() - $(self).offset().top;
              $(ele).data('startPos', top);
          });
      }
  }
});
#wrapper {
    border: 3px solid black;
    width: 400px;
    height: 300px;
    margin: 10px auto 0;
    overflow: hidden;
}

#div1 {
    width: 4000px;
    height: 500px;
    overflow-y: auto;
    overflow-x: auto;
    border: 1px solid red;
    margin: 5px 0 0 5px;
}

#div2 {
    width: 4000px;
    height: 500px;
    overflow-y: auto;
    overflow-x: auto;
    border: 1px solid red;
    margin: 5px 0 0 5px;
}

.box {
    float: left;
    border: 1px solid green;
    width: 200px;
    height: 600px;
}

.box h2 {
    margin: 0 auto;
    text-align: center;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/jquery.scrollto@2.1.2/jquery.scrollTo.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/jquery.localscroll@2.0.0/jquery.localScroll.min.js"></script>

<a href="#section1.1">go to section 1.1</a>
<br>
<a href="#section1.2">go to section 1.2</a>
<br>
<a href="#section1.3">go to section 1.3</a>
<br>
<a href="#section2.1">go to section 2.1</a>
<br>
<a href="#section2.2">go to section 2.2</a>
<br>
<a href="#section2.3">go to section 2.3</a>

<div id="wrapper">
    <div id="div1">
        <div class="box" id="section1.1">
            <h2>content 1.1</h2>
        </div>
        <div class="box" id="section1.2">
            <h2>content 1.2</h2>
        </div>
        <div class="box" id="section1.3">
            <h2>content 1.3</h2>
        </div>
        <div class="box" id="section1.4">
            <h2>content 1.4</h2>
        </div>
        <div class="box" id="section1.5">
            <h2>content 1.5</h2>
        </div>
        <div class="box" id="section1.6">
            <h2>content 1.6</h2>
        </div>
    </div>
    <div id="div2">
        <div class="box" id="section2.1">
            <h2>content 2.1</h2>
        </div>
        <div class="box" id="section2.2">
            <h2>content 2.2</h2>
        </div>
        <div class="box" id="section2.3">
            <h2>content 2.3</h2>
        </div>
        <div class="box" id="section2.4">
            <h2>content 2.4</h2>
        </div>
        <div class="box" id="section2.5">
            <h2>content 2.5</h2>
        </div>
        <div class="box" id="section2.6">
            <h2>content 2.6</h2>
        </div>
    </div>
</div>