【问题标题】:How to Fix Event Conflicts Between Swiper and Video.Js如何修复 Swiper 和 Video.Js 之间的事件冲突
【发布时间】:2021-10-26 15:48:39
【问题描述】:

我正在使用 Swiper 制作带有图像和视频的简单幻灯片。这就像一个魅力。但是,由于设计要求是具有一致且美观的播放器 UI,因此我需要使用 Video.js 作为视频播放器。所以我有 Swiper 作为幻灯片插件和 Video.js 作为视频插件。除了这两个插件之间存在事件冲突之外,这是可行的。

Swiper 在其根目录上有一个 mousedown 事件,而 Video.js 在视频及其(由 Video.js 动态创建的)父容器上也有一个 mousedown 事件。当拖动幻灯片(视频)时,不仅 Swiper 检测到它必须滑动,而且 Video.js 也会在点击视频时处理这个问题。 因此,如果您滑动到下一张幻灯片,这始终意味着视频正在播放/暂停。

此外,当您在时间轴上拖动圆圈时,Swiper 也会检测到滑动。

是否有机会修补两个事件侦听器以协同工作?我正在寻找一种无需修补库本身的方法。此外,补丁不应影响插件的原始行为。

这是我要引用的代码。你也可以玩this jsfiddle

var swiper = new Swiper('.swiper-container', {
  pagination: '.swiper-pagination',
  paginationClickable: true,
  nextButton: '.swiper-button-next',
  prevButton: '.swiper-button-prev',
  spaceBetween: 30
});

[...document.querySelectorAll('video')].forEach(video => {
  video.classList.add('video-js');
  video.classList.add('vjs-default-skin');
  video.classList.add('vjs-big-play-centered');
  videojs(video, {
    fluid: true,
    autoplay: true
  });
});
html,
body {
  position: relative;
  height: 100%;
}

body {
  background: #eee;
  font-family: Helvetica Neue, Helvetica, Arial, sans-serif;
  font-size: 14px;
  color: #000;
  margin: 0;
  padding: 0;
}

.swiper-container {
  width: 100%;
  height: 100%;
}

.swiper-slide {
  text-align: center;
  font-size: 18px;
  background: #fff;
  /* Center slide text vertically */
  display: -webkit-box;
  display: -ms-flexbox;
  display: -webkit-flex;
  display: flex;
  -webkit-box-pack: center;
  -ms-flex-pack: center;
  -webkit-justify-content: center;
  justify-content: center;
  -webkit-box-align: center;
  -ms-flex-align: center;
  -webkit-align-items: center;
  align-items: center;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/Swiper/3.4.2/css/swiper.min.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/Swiper/3.4.2/js/swiper.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/video.js/6.2.5/video-js.min.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/video.js/6.2.5/video.min.js"></script>

<!-- Swiper -->
<div class="swiper-container">
  <div class="swiper-wrapper">
    <div class="swiper-slide">
      <video preload="auto" muted loop controls>
        <source src="https://dwknz3zfy9iu1.cloudfront.net/uscenes_h-264_hd_test.mp4" type="video/mp4">
      </video>
    </div>
    <div class="swiper-slide">Slide 2</div>
    <div class="swiper-slide">
      <video preload="auto" muted loop controls>
        <source src="https://dwknz3zfy9iu1.cloudfront.net/uscenes_h-264_hd_test.mp4" type="video/mp4">
      </video>
    </div>
    <div class="swiper-slide">Slide 4</div>
    <div class="swiper-slide">Slide 5</div>
    <div class="swiper-slide">Slide 6</div>
    <div class="swiper-slide">Slide 7</div>
    <div class="swiper-slide">Slide 8</div>
    <div class="swiper-slide">Slide 9</div>
    <div class="swiper-slide">Slide 10</div>
  </div>
  <!-- Add Pagination -->
  <div class="swiper-pagination"></div>
  <!-- Add Arrows -->
  <div class="swiper-button-next"></div>
  <div class="swiper-button-prev"></div>
</div>

【问题讨论】:

    标签: javascript event-handling mouseevent video.js swiper


    【解决方案1】:

    您可以向选项noSwipingClass 添加一个类,以防止 Swiper 使用该类处理幻灯片上的事件。现在只有下一个/上一个 Swiper 按钮可以在视频幻灯片上使用。也许是一个合理的妥协。

    例如。

    var swiper = new Swiper('.swiper-container', {
      nextButton: '.swiper-button-next',
      prevButton: '.swiper-button-prev',
      spaceBetween: 30,
      noSwipingClass: 'swiper-no-swiping'
    });
    

    与:

    <!-- Swiper -->
    <div class="swiper-container">
      <div class="swiper-wrapper">
        <div class="swiper-slide swiper-no-swiping" oncouseo>
          <video preload="auto" muted loop controls>
            <source src="https://dwknz3zfy9iu1.cloudfront.net/uscenes_h-264_hd_test.mp4" type="video/mp4">
          </video>
        </div>
        <div class="swiper-slide">Slide 2</div>
        <div class="swiper-slide swiper-no-swiping">
          <video preload="auto" muted loop controls>
            <source src="https://dwknz3zfy9iu1.cloudfront.net/uscenes_h-264_hd_test.mp4" type="video/mp4">
          </video>
        </div>
        <div class="swiper-slide">Slide 4</div>
        <div class="swiper-slide">Slide 5</div>
      </div>
      <!-- Add Arrows -->
      <div class="swiper-button-next"></div>
      <div class="swiper-button-prev"></div>
    </div>
    

    演示:https://jsfiddle.net/zqhLqfck/

    【讨论】:

    • 谢谢!如果其他人有不同的方法仍然允许刷卡,我会等待。
    【解决方案2】:

    另一种方法,但更符合您的要求,是在视频上添加叠加层,仅将点击事件传递给视频。

    它将叠加层拉伸到视频区域的大小,同时排除底部的视频控制栏。

    在控制栏的div 中添加“swiper-no-swiping”类以阻止Swiper 识别视频手势。

    现在在叠加层上滑动不会导致视频播放或暂停,但点击它会导致视频控制栏的手势被 Swiper 忽略。

    当然可见的 CSS 和文字只是为了帮助说明覆盖,会被移除。

    var swiper = new Swiper('.swiper-container', {
      pagination: '.swiper-pagination',
      paginationClickable: true,
      nextButton: '.swiper-button-next',
      prevButton: '.swiper-button-prev',
      spaceBetween: 30,
      noSwipingClass: 'swiper-no-swiping'
    });
    
    [...document.querySelectorAll('video')].forEach(video => {
      video.classList.add('video-js');
      video.classList.add('vjs-default-skin');
      video.classList.add('vjs-big-play-centered');
      videojs(video, {
        fluid: true,
        autoplay: true
      });
    });
    
    $(function() {
    
      var $overlay = $("#video-overlay1");
      var myPlayer = videojs('vid1');
      var $overlayArea = $("#vid1 > .vjs-text-track-display");
    
      // apply overlay on video to prevent swipes playing/pausing the video
      positionVideoOverlay();
    
      // prevent swiping action on video control bar
      $(".vjs-control-bar").addClass("swiper-no-swiping");
    
      $overlay.click(function() {
        if (myPlayer.paused())
          myPlayer.play();
        else
          myPlayer.pause();
      });
    
      $(window).resize(function() {
        positionVideoOverlay();
      });
    
      function positionVideoOverlay() {
        $overlay.css("width", $overlayArea.width() + "px");
        $overlay.css("height", $overlayArea.height() + "px");
        $overlay.css("top", $overlayArea.offset().top + "px")
      }
    });
    
    .video-overlay {
      position: absolute;
      left: 0;
      top: 0;
      font-size: 20px;
      font-family: Helvetica;
      color: #FFF;
      background-color: rgba(50, 50, 50, 0.8);
    }
    
    <div class="swiper-container">
      <div class="swiper-wrapper">
        <div class="swiper-slide">
          <video id="vid1" preload="auto" muted loop controls>
                <source src="https://dwknz3zfy9iu1.cloudfront.net/uscenes_h-264_hd_test.mp4" type="video/mp4">
              </video>
          <div id="video-overlay1" class="video-overlay">Overlay that will pass clicks to video layer
            <br>But will not pass swipe gestures</div>
        </div>
        <div class="swiper-slide">Slide 2</div>
        <div class="swiper-slide">Slide 3</div>
      </div>
      <!-- Add Pagination -->
      <div class="swiper-pagination"></div>
      <!-- Add Arrows -->
      <div class="swiper-button-next"></div>
      <div class="swiper-button-prev"></div>
    </div>
    

    演示基本概念:https://jsfiddle.net/1vqozv25/4/

    【讨论】:

    • 虽然这适用于实际视频,但不适用于视频播放器。正如您在this example 中看到的,如果您将覆盖的 div 定位为完全覆盖视频,请单击“静音”或“全屏”按钮,否则时间线将不会执行任何操作。此外,您不能像在其他 Video.js 示例中那样拖动时间线圆圈。其中一项要求是:the patch should not affect the original behavior of the plugins.
    • 这就是为什么我说“不包括底部的控制栏”。它应该只覆盖&lt;div class="vjs-text-track-display"&gt;的区域
    • 如果您从叠加层中排除时间线,我们将遇到与以前相同的问题:如果您在时间线上拖动圆圈 Swiper 幻灯片。
    • 编辑了我的答案。它将noSwipingClass: 'swiper-no-swiping' 类添加到视频控制栏,并设置覆盖的高度和位置。 jsfiddle.net/1vqozv25/3
    • 添加了调整窗口大小时调整覆盖的代码 - jsfiddle.net/1vqozv25/4
    【解决方案3】:

    这将只为视频js的控制栏设置无滑动。

    $( ".vjs-control-bar" ).addClass('swiper-no-swiping');

    滑动仍然适用于视频 div。

    【讨论】:

      【解决方案4】:

      与 Manev 的回答类似,带有 noSwipingClass: 'vjs-control-bar' 选项的 init Swiper 也可以工作。

      var swiper = new Swiper('.swiper-container', {
        noSwipingClass: 'vjs-control-bar'
      });
      

      【讨论】:

        猜你喜欢
        • 2015-07-07
        • 2012-04-07
        • 1970-01-01
        • 2021-01-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多