Проблема с localScroll при использовании с прокручиваемыми элементами

#jquery #plugins #scroll #scrollto

#jquery #Плагины #прокрутка #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>  

Сценарий:

Существует оболочка (небольшого размера), внутри которой находятся два больших прокручиваемых раздела (один за другим) с шестью плавающими элементами высотой больше, чем у их родителей, чтобы пользователь мог использовать прокрутку. В резюме «карта» выглядит следующим образом:

| 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-индекс). 3. Установите положение прокручиваемого div в начало перед началом перемещения.

Результат всегда один и тот же: оба divs выглядят так, как будто они оба сталкиваются / раздавливаются

Есть идеи? Заранее спасибо!

Ответ №1:

Текст полей выглядит как скрытый. Если вы прокрутите поля раздела 2, то увидите содержимое, но вы можете увидеть, что плагин не привел вас в правильное положение.

Проблему можно решить с помощью обратных вызовов offset и onAfter:

  • onAfter: сохраните текущую верхнюю позицию для каждого якоря, только в первый раз
  • смещение: снова вычислите текущую вершину и, если отличается (см. событие прокрутки), верните смещение, чтобы компенсировать его

Для того, чтобы компенсировать прокрутку, вам также необходимо добавить в обратный вызов offset вызов анимации прокрутки.

     $.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 amp;amp; 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 amp;amp; 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>  

Комментарии:

1. Спасибо за попытку, но это не решение, потому что, как вы можете видеть, это полностью нарушает движение анимации.

2. Обновлен ответ @cooper и фрагмент текста. Дайте мне знать. Спасибо

3. Я получаю ошибку: «Ошибка типа: привязка. данные не являются функцией», и это «подавляет» анимацию : (

4. работает ли это во фрагменте? Я предполагаю, что должна быть разница в вашем коде: библиотеки html или jquery

5. После долгого времени я попробовал снова. Это сработало отлично. Спасибо.