Sticky Video
在给客户做Wordpress定制开发时遇到这样一个需求,网页播放视频时,滚动浏览器,视频窗口自动缩放至窗口右下角,便于浏览网页与观看视频同步进行。
个人觉得这个功能还是挺有趣,现在分享给大家。
(function (global) {
'use strict'
var StickyVideo = function (containerId) {
this.containerId = containerId || 'sticky-container'
this.container = document.getElementById(this.containerId)
this.initialize()
}
StickyVideo.addClass = addClass
StickyVideo.removeClass = removeClass
StickyVideo.hasClass = hasClass
StickyVideo.wrap = wrap
StickyVideo.insertAfter = insertAfter
StickyVideo.prototype.fixElementHeight = fixElementHeight
StickyVideo.prototype.elementInViewport = elementInViewport
StickyVideo.prototype.initialize = initialize
function fixElementHeight () {
this.container.parentElement.style.height = this.container.parentElement.offsetHeight + 'px'
}
function addClass (elements, className) {
if (hasClass(elements, className)) return
if (!elements) { return }
if (typeof elements === 'string') {
elements = document.querySelectorAll(elements)
} else if (elements.tagName) { elements = [elements] }
for (var i = 0; i < elements.length; i++) {
if ((' ' + elements[i].className + ' ').indexOf(' ' + className + ' ') < 0) {
elements[i].className += ' ' + className
}
}
}
function removeClass (elements, className) {
if (!hasClass(elements, className)) return
if (!elements) { return }
if (typeof elements === 'string') {
elements = document.querySelectorAll(elements)
} else if (elements.tagName) { elements = [elements] }
var reg = new RegExp('(^| )' + className + '($| )', 'g')
for (var i = 0; i < elements.length; i++) {
elements[i].className = elements[i].className.replace(reg, '')
}
}
function hasClass (element, className) {
return new RegExp('(\\s|^)' + className + '(\\s|$)').test(element.className)
}
function wrap (toWrap, wrapper) {
return wrapper.appendChild(toWrap)
}
function insertAfter (el, referenceNode) {
referenceNode.parentNode.insertBefore(el, referenceNode.nextSibling)
}
function elementInViewport (el) {
var rect = el.getBoundingClientRect()
return (rect.top > (el.offsetHeight * -1))
}
function initialize () {
if (!this.container) return
var that = this
var wrapDiv = document.createElement('div')
function onWindowScroll () {
that.fixElementHeight()
var parent = wrapDiv
if (!that.elementInViewport(parent)) {
StickyVideo.removeClass(parent, 'sticky-container_in-content')
StickyVideo.addClass(parent, 'sticky-container_sticky')
} else {
StickyVideo.removeClass(parent, 'sticky-container_sticky')
StickyVideo.addClass(parent, 'sticky-container_in-content')
}
}
wrapDiv.className = 'sticky-container__wrap'
this.container.parentElement.insertBefore(wrapDiv, this.container)
StickyVideo.insertAfter(wrapDiv, that.container)
StickyVideo.wrap(that.container, wrapDiv)
StickyVideo.addClass(wrapDiv, 'sticky-container_in-content')
StickyVideo.addClass(that.container, 'sticky-container__video')
window.addEventListener ? window.addEventListener('scroll', onWindowScroll) : window.onscroll = onWindowScroll
}
// AMD support
if (typeof define === 'function' && define.amd) {
define(function () { return StickyVideo })
// CommonJS and Node.js module support.
} else if (typeof exports !== 'undefined') {
// Support Node.js specific `module.exports` (which can be a function)
if (typeof module !== 'undefined' && module.exports) {
exports = module.exports = StickyVideo
}
// But always support CommonJS module 1.1.1 spec (`exports` cannot be a function)
exports.StickyVideo = StickyVideo
} else {
global.StickyVideo = StickyVideo
}
})(this)
JavaScript<script>
new StickyVideo('sticky-container')
</script>
JavaScript.sticky-container__video {
height: 270px;
width: 480px;
right: 0;
bottom: 0;
position: fixed;
}
.sticky-container_in-content .sticky-container__video {
padding-bottom: 56.25%;
position: relative;
height: 0; width: auto;
position: relative;
bottom: auto; right: auto;
overflow: hidden;
}
.sticky-container_in-content .sticky-container__video .sticky-container__object {
position: absolute;
top:0;
left: 0;
width: 100%;
height: 100%;
}
CSS