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 极速浏览器的极速模式效果如下:
使用 360 极速浏览器的 ie 兼容模式效果如下:
原因是我们在 css 代码里面使用了 object-fit: fill;
,而 object-fit
在 ie 模式下是不兼容的。
https://caniuse.com/?search=object-fit
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 兼容模式效果如下: