video.js 自定义全屏按钮,解决全屏弹幕被遮挡问题

来源:简书 分类: 文章浏览史 发布时间:2021-11-17 11:33:02 最后更新:2021-11-17 浏览:360
转载声明:
本文为摘录自“简书”,版权归原作者所有。
温馨提示:
为了更好的体验,请点击原文链接进行浏览
摘录时间:
2021-11-17 11:33:02

需求说明:使用video.js播放视频,要求点击全屏按钮的时候,弹幕可以跟视频一起全屏。

看起来是个很简单的需求,直觉上只要在全屏后,只要让弹幕的z-index高过全屏的视频不就可以了吗。

但是实际上,全屏的元素层级似乎是最高的,用z-index无法实现弹幕在全屏视频上出现的效果。

使用requestFullScreen, exitFullscreen, fullscreenchange事件实现全屏效果

Element.requestFullscreen()可以实现div元素的全屏,那么只要把弹幕和<video>标签放在同一个父div里,就可以实现全屏时弹幕在<video>上的效果了:

<div class="playerLive">
  <video></video>
  <canvas class="danmu"></canvas>
</div>
const playerLive = document.querySelector('playerLive');
videoWrapper.requestFullscreen();

只要在父元素下,弹幕的层级比<video>高,弹幕在视频上方的效果就能实现了。

不过,在使用的过程中需要注意,requestFullscreen使用时需要加上webkit,ms,moz等浏览器前缀,解决浏览器的兼容问题:

if (playerLive.requestFullscreen) {
  return playerLive.requestFullscreen();
} else if (playerLive.webkitRequestFullScreen) {
  return playerLive.webkitRequestFullScreen();
} else if (playerLive.mozRequestFullScreen) {
  return playerLive.mozRequestFullScreen();
} else (playerLive.msRequestFullscreen) {
  playerLive.msRequestFullscreen();
}

而且,Element.requestFullscreen()在IE只支持IE11+。

document.exitFullscreen()可以让当前页面内退出全屏模式,要注意的是这个api是在document上,不需要是全屏的那个元素。

fullscreenchange事件可以监听页面的全屏状态,页面全屏/退出全屏都能触发fullscreenchange事件。同样需要给监听事件添加浏览器前缀。

结合video.js的处理方案

因为video.js已经自带了一个全屏按钮,我曾想看看文档里有没有支持重写全屏按钮的api或者配置,但是翻边了文档还是没找到(如果有大佬知道欢迎告知哈哈),所以只能使用video.js提供的controlBar.addChild重写全屏按钮,还可以复用全屏按钮的样式,除此之外,还要判断浏览器版本,如果是IE浏览器,就使用video.js提供的全屏按钮:

let isFullScreen = false;
const player = videojs(‘#player’, {
      controlBar: {
       // 非IE浏览器隐藏全屏按钮
        fullscreenToggle: !!videojs.browser.IE_VERSION
      }
});
// 创建全屏按钮
createFullScreenBtn() {
      const btn = player.controlBar.addChild('button', {
        clickHandler: triggerFullScreen
      });
      btn.addClass('vjs-fullscreen-control');
      btn.addClass('vjs-control');
      btn.addClass('vjs-button');

     const playerLive = document.querySelector('#player-live');
      [
        'fullscreenchange',
        'webkitfullscreenchange',
        'mozfullscreenchange'
      ].forEach((fullScreenCHange) => {
        playerLive.addEventListener(fullScreenCHange, (e) => {
          isFullScreen = !this.isFullScreen;
        });
      });
}

triggerFullScreen() {
  const playerLive = document.querySelector('#player-live');
  if (isFullScreen) {
   // 使用video.js提供的exitFullscreen api,避免原生exitFullscreen的兼容问题
   player.exitFullscreen();
  } else {
    try {
      if (playerLive.requestFullscreen) {
        return playerLive.requestFullscreen();
      } else if (playerLive.webkitRequestFullScreen) {
        return playerLive.webkitRequestFullScreen();
      } else if (playerLive.mozRequestFullScreen) {
        return playerLive.mozRequestFullScreen();
      } else if (playerLive.msRequestFullscreen) {
        playerLive.msRequestFullscreen();
      } else {
        this.creator.player.requestFullscreen();
      }
    } catch (err) {
      // 如果原生全屏api出错,则使用video.js自带的全屏api
      player.requestFullscreen();
    }
  }
}
php技术微信