Полноэкранный режим BXSlider 4 на мобильных устройствах: как сохранить собственную вертикальную прокрутку страницы (вверх, вниз), но сохранить функциональность горизонтального касания (слева, справа)? - PullRequest
0 голосов
/ 05 сентября 2018

Следующий фрагмент должен хорошо продемонстрировать проблему:

(function ($) {

    $('.bxslider').each(function() {
        var bxid = $(this).attr("data-bxid");

        var bx = $(this).bxSlider({
            auto: false,
            autoStart: false
        });
    });

})(jQuery);
/* Styles */
#before, #after {
  width:350px;
  height:350px;
  background-color:#ccf;
}

/* BXSlider */
.bx-wrapper {
  position: relative;
  margin-bottom: 60px;
  padding: 0;
  *zoom: 1;
  -ms-touch-action: pan-y;
  touch-action: pan-y;
}

.bx-wrapper img {
  max-width: 100%;
  display: block;
}

.bxslider {
  background-color:#eee;
  margin: 0;
  padding: 0;
  /*fix flickering when used background-image instead of <img> (on Chrome)*/
  -webkit-perspective: 1000;
}

ul.bxslider {
  list-style: none;
  width:100%;
}

ul.bxslider li {
   width:100%;
}

.bx-viewport {
  /* fix other elements on the page moving (in Chrome) */
  -webkit-transform: translateZ(0);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/bxslider/4.2.15/jquery.bxslider.min.js"></script>
<div id="before"></div>
<ul class="bxslider">
<li><p>If you touch me vertically ...<img src="https://via.placeholder.com/500x350"></li>
<li>... I want to scroll down normally ...<img src="https://via.placeholder.com/500x250"></li>
<li>... but nothing happens ?<img src="https://via.placeholder.com/500x450"></li>
</ul>
<div id="after"></div>

В инструментах разработчика вашего окна браузера попробуйте прокрутить вниз прикосновением внутри бегущего фрагмента кода - это невозможно. Однако это не вариант, так как с полноэкранным горизонтальным bxSlider посетители теряют возможность просмотра сайта полностью - недопустимо!

bxSlider предоставляет следующие настройки:

touchEnabled:false

Однако это также не вариант, поскольку посетители смартфона действительно должны иметь возможность переключать слайды вправо / влево пальцами.

Поэтому мне нужна такая возможность:

  • ГОРИЗОНТАЛЬНОЕ касание: Плавно переходите к следующему / предыдущему слайду в пределах ползунка.
  • ВЕРТИКАЛЬНОЕ движение касанием: Просто продолжайте обычную прокрутку окна просмотра в браузере.

К сожалению, я не нашел ни одной комбинации настроек bxslider, как этого добиться. Знаете ли вы решение для этого (желательно без изменения самого файла ядра bxslider)?

1 Ответ

0 голосов
/ 14 сентября 2018

Я отредактировал onTouchStart функцию в jquery.bxslider.js .

Просто скопируйте и замените приведенные ниже коды на оригинальные коды функций onTouchStart (начинающиеся со строки 1103):

   var onTouchStart = function(e) {
      // watch only for left mouse, touch contact and pen contact
      // touchstart event object doesn`t have button property
      if (e.type !== 'touchstart' && e.button !== 0) {
        return;
      }
      var lastScrollTop = 0;
        $(window).scroll(function(event){
            var st = $(this).scrollTop();
            if (st > lastScrollTop){ } else {  e.preventDefault();   }
        });

      //disable slider controls while user is interacting with slides to avoid slider freeze that happens on touch devices when a slide swipe happens immediately after interacting with slider controls
      slider.controls.el.addClass('disabled');

      if (slider.working) {
        slider.controls.el.removeClass('disabled');
      } else {
        // record the original position when touch starts
        slider.touch.originalPos = el.position();
        var orig = e.originalEvent,
        touchPoints = (typeof orig.changedTouches !== 'undefined') ? orig.changedTouches : [orig];
        var chromePointerEvents = typeof PointerEvent === 'function'; 
        if (chromePointerEvents) { 
            if (orig.pointerId === undefined) { 
                return;
            } 
        }
        // record the starting touch x, y coordinates
        slider.touch.start.x = touchPoints[0].pageX;
        slider.touch.start.y = touchPoints[0].pageY;

        if (slider.viewport.get(0).setPointerCapture) {
          slider.pointerId = orig.pointerId;
          slider.viewport.get(0).setPointerCapture(slider.pointerId);
        }
        // store original event data for click fixation
        slider.originalClickTarget = orig.originalTarget || orig.target;
        slider.originalClickButton = orig.button;
        slider.originalClickButtons = orig.buttons;
        slider.originalEventType = orig.type;
        // at this moment we don`t know what it is click or swipe
        slider.hasMove = false;
        // on a "touchmove" event to the viewport
        slider.viewport.on('touchmove MSPointerMove pointermove', onTouchMove);
        // on a "touchend" event to the viewport
        slider.viewport.on('touchend MSPointerUp pointerup', onTouchEnd);
        slider.viewport.on('MSPointerCancel pointercancel', onPointerCancel);
      }
    };

Редактировать (Fiddle): https://jsfiddle.net/Blackbam/sk2ve907/2/

Для тестирования: https://jsfiddle.net/Blackbam/sk2ve907/2/show

...