web页面实现全背景视频功能方案:使用bideo.js来处理object-fit在ie浏览器下不兼容问题

时间:2023-02-09 07:53:38

object-fit 兼容问题

【视频资源】:https://raw.githubusercontent.com/rishabhp/bideo.js/master/night.mp4

先看下面例子:

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8" />
        <meta http-equiv="X-UA-Compatible" content="IE=edge" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>全屏HTML5网页背景视频</title>
        <style>
            html,
            body {
                margin: 0;
                padding: 0;
            }
            #container {
                overflow: hidden;
                position: absolute;
                top: 0;
                left: 0;
                right: 0;
                bottom: 0;
                text-align: center;
            }
            #main {
                display: inline-block;
                position: relative;
                top: 50%;
                transform: translateY(-50%);
                color: #fff;
            }
            #video {
                width: 100%;
                height: 100%; 
                position: absolute;
                top: 0;
                left: 0;
                z-index: -1;
                object-fit: fill;
            }
        </style>
    </head>
    <body>
        <div id="container">
            <!-- 内容 -->
            <section id="main">
                <div id="head">
                    <h1>Bideo.js</h1>
                    <p class="sub_head">A JS library that makes it super easy to add fullscreen background videos.</p>
                </div>
            </section>
            <!-- 视频背景 -->
            <video id="video" src="/night.mp4" autoplay loop muted></video>
        </div>
    </body>
</html>

使用 360 极速浏览器的极速模式效果如下:

web页面实现全背景视频功能方案:使用bideo.js来处理object-fit在ie浏览器下不兼容问题

使用 360 极速浏览器的 ie 兼容模式效果如下:

web页面实现全背景视频功能方案:使用bideo.js来处理object-fit在ie浏览器下不兼容问题

原因是我们在 css 代码里面使用了 object-fit: fill;,而 object-fit 在 ie 模式下是不兼容的。

https://caniuse.com/?search=object-fit

web页面实现全背景视频功能方案:使用bideo.js来处理object-fit在ie浏览器下不兼容问题

bideo.js

为了解决上面 object-fit 在 ie 模式下不兼容的问题,这里我们使用 bideo.js,它能实现全屏HTML5网页背景视频。

GitHub地址:https://github.com/rishabhp/bideo.js

Fullscreen HTML5 Background Video for the Web.

/**
 * Full Background Video
 *
 * More info on Audio/Video Media Events/Attributes/Methods
 * - https://developer.mozilla.org/en-US/docs/Web/Guide/Events/Media_events
 * - http://www.w3schools.com/tags/ref_av_dom.asp
 */

(function (global) {

  // Define Bideo constructor on the global object
  global.Bideo = function () {

    // Plugin options
    this.opt = null;
    // The Video element
    this.videoEl = null;

    // Approximate Loading Rate
    //
    // The value will be a number like 0.8
    // which means to load 4 seconds of the video
    // it takes 5 seconds. If the number is super low
    // like 0.2 (regular 3g connections) then you can
    // decide whether to play the video or not.
    // This behaviour will be controller with
    // the `acceptableLoadingRate` option.
    this.approxLoadingRate = null;

    // Methods to which `this` will be bound
    this._resize = null;
    this._progress = null;

    // Time at which video is initialized
    this.startTime = null;

    this.onLoadCalled = false;

    // Initialize and setup the video in DOM`
    this.init = function (opt) {
      // If not set then set to an empty object
      this.opt = opt = opt || {};

      var self = this;

      self._resize = self.resize.bind(this);

      // Video element
      self.videoEl = opt.videoEl;

      // Meta data event
      self.videoEl.addEventListener('loadedmetadata', self._resize, false);

      // Fired when enough has been buffered to begin the video
      // self.videoEl.readyState === 4 (HAVE_ENOUGH_DATA)
      self.videoEl.addEventListener('canplay', function () {
        // Play the video when enough has been buffered
        if (!self.opt.isMobile) {
          self.opt.onLoad && self.opt.onLoad();
          if (self.opt.autoplay !== false) self.videoEl.play();
        }
      });

      // If resizing is required (resize video as window/container resizes)
      if (self.opt.resize) {
        global.addEventListener('resize', self._resize, false);
      }

      // Start time of video initialization
      this.startTime = (new Date()).getTime();

      // Create `source` for video
      this.opt.src.forEach(function (srcOb, i, arr) {
        var key
          , val
          , source = document.createElement('source');

        // Set all the attribute key=val supplied in `src` option
        for (key in srcOb) {
          if (srcOb.hasOwnProperty(key)) {
            val = srcOb[key];

            source.setAttribute(key, val);
          }
        }

        self.videoEl.appendChild(source);
      });

      if (self.opt.isMobile) {
        if (self.opt.playButton) {
          self.opt.videoEl.addEventListener('timeupdate', function () {
            if (!self.onLoadCalled) {
              self.opt.onLoad && self.opt.onLoad();
              self.onLoadCalled = true;
            }
          });


          self.opt.playButton.addEventListener('click', function () {
            self.opt.pauseButton.style.display = 'inline-block';
            this.style.display = 'none';

            self.videoEl.play();
          }, false);

          self.opt.pauseButton.addEventListener('click', function () {
            this.style.display = 'none';
            self.opt.playButton.style.display = 'inline-block';

            self.videoEl.pause();
          }, false);
        }
      }

      return;
    }

    // Called once video metadata is available
    //
    // Also called when window/container is resized
    this.resize = function () {
      // IE/Edge still don't support object-fit: cover
      if ('object-fit' in document.body.style) return;

      // Video's intrinsic dimensions
      var w = this.videoEl.videoWidth
        , h = this.videoEl.videoHeight;

      // Intrinsic ratio
      // Will be more than 1 if W > H and less if H > W
      var videoRatio = (w / h).toFixed(2);

      // Get the container DOM element and its styles
      //
      // Also calculate the min dimensions required (this will be
      // the container dimentions)
      var container = this.opt.container
        , containerStyles = global.getComputedStyle(container)
        , minW = parseInt( containerStyles.getPropertyValue('width') )
        , minH = parseInt( containerStyles.getPropertyValue('height') );

      // If !border-box then add paddings to width and height
      if (containerStyles.getPropertyValue('box-sizing') !== 'border-box') {
        var paddingTop = containerStyles.getPropertyValue('padding-top')
          , paddingBottom = containerStyles.getPropertyValue('padding-bottom')
          , paddingLeft = containerStyles.getPropertyValue('padding-left')
          , paddingRight = containerStyles.getPropertyValue('padding-right');

        paddingTop = parseInt(paddingTop);
        paddingBottom = parseInt(paddingBottom);
        paddingLeft = parseInt(paddingLeft);
        paddingRight = parseInt(paddingRight);

        minW += paddingLeft + paddingRight;
        minH += paddingTop + paddingBottom;
      }

      // What's the min:intrinsic dimensions
      //
      // The idea is to get which of the container dimension
      // has a higher value when compared with the equivalents
      // of the video. Imagine a 1200x700 container and
      // 1000x500 video. Then in order to find the right balance
      // and do minimum scaling, we have to find the dimension
      // with higher ratio.
      //
      // Ex: 1200/1000 = 1.2 and 700/500 = 1.4 - So it is best to
      // scale 500 to 700 and then calculate what should be the
      // right width. If we scale 1000 to 1200 then the height
      // will become 600 proportionately.
      var widthRatio = minW / w;
      var heightRatio = minH / h;

      // Whichever ratio is more, the scaling
      // has to be done over that dimension
      if (widthRatio > heightRatio) {
        var new_width = minW;
        var new_height = Math.ceil( new_width / videoRatio );
      }
      else {
        var new_height = minH;
        var new_width = Math.ceil( new_height * videoRatio );
      }

      this.videoEl.style.width = new_width + 'px';
      this.videoEl.style.height = new_height + 'px';
    };

  };

}(window));

使用bideo.js实现全背景视频

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8" />
        <meta http-equiv="X-UA-Compatible" content="IE=edge" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>全屏HTML5网页背景视频</title>
        <style>
            html,
            body {
                margin: 0;
                padding: 0;
            }
            #container {
                overflow: hidden;
                position: absolute;
                top: 0;
                left: 0;
                right: 0;
                bottom: 0;
                text-align: center;
            }
            #main {
                display: inline-block;
                position: relative;
                top: 50%;
                transform: translateY(-50%);
                color: #fff;
            }
            #video {
                width: 100%;
                height: 100%; 
                position: absolute;
                top: 0;
                left: 0;
                z-index: -1;
                object-fit: fill;
            }
        </style>
        <script src="./bideo.js"></script>
    </head>
    <body>
        <div id="container">
            <!-- 内容 -->
            <section id="main">
                <div id="head">
                    <h1>Bideo.js</h1>
                    <p class="sub_head">A JS library that makes it super easy to add fullscreen background videos.</p>
                </div>
            </section>
            <!-- 视频背景 -->
            <video id="video" src="/night.mp4" autoplay loop muted></video>
        </div>
        <script>
            window.onload = function() {
                (function () {
                    let bv = new Bideo();
                    bv.init({
                        // Video element
                        videoEl: document.querySelector("#video"),
                        // Container element
                        container: document.querySelector("body"),
                        // Resize
                        resize: true,
                        // Array of objects containing the src and type
                        // of different video formats to add
                        src: [],
                        // What to do once video loads (initial frame)
                        onLoad: function () {}
                    });
                })();
            }
        </script>
    </body>
</html>

bideo.js 之后,360 极速浏览器的 ie 兼容模式效果如下:

web页面实现全背景视频功能方案:使用bideo.js来处理object-fit在ie浏览器下不兼容问题