课程名称:TypeScript封装播放器组件
课程章节:第5章 弹出层中的Video播放器组件开发 5-1 5-2
课程讲师:西门老舅
课程内容:
今天学习的内容是实现视频播放器组件。
视频组件框架搭建
在 src/components 目录下新建 Video目录,存放视频组件的内容:
src/components
|- Video
|- index.ts # 组件结构
|- index.css # 组件样式
使用接口定义播放器组件的构造参数类型:
interface IVideo {
// 视频播放地址
url: string,
// 播放器组件挂载的父节点
elm: string | HTMLElement,
// 组件尺寸
width?: string,
height?: string,
// 是否自动播放
autoplay?: boolean
}
使用面向对象的思想来实现组件,基本结构为:
// video/index.ts
import { IComponent } from '../types'
class Video implements IComponent {
tempContainer!: HTMLElement;
constructor(private options: IVideo) {
this.options = Object.assign({
width: '100%',
height: '100%',
autoplay: false
}, options)
this.init()
}
init() {
this.template()
this.handle()
}
template() {}
handle() {}
}
function createVideo(options: IVideo) {
return new Video(options)
}
export default createVideo
播放器布局结构
播放器组件分为两部分,一部分通过 标签播放视频,一部分实现一个播放控件。
播放控件的结构稍微复杂一些,包含了进度条、播放按钮、播放时间、音量条、全屏按钮。
在 template 方法中实现布局结构:
template() {
this.tempContainer = document.createElement('div')
this.tempContainer.className = 'video'
this.tempContainer.style.width = this.options.width as string
this.tempContainer.style.height = this.options.height as string
this.tempContainer.innerHTML = `
<video class="video-content" src="${this.options.url}"> </video>
<div class="video-controls">
<!-- 进度条 -->
<div class="video-progress">
<div class="video-progress-now"></div>
<div class="video-progress-suc"></div>
<div class="video-progress-bar"></div>
</div>
<!-- 控制按钮 -->
<div class="btn-group">
<div class="left">
<div class="video-play">
<i class="iconfont icon-play"></i>
</div>
<div class="video-time">
<span class="start">00:00</span>
<span>/</span>
<span class="total">00:00</span>
</div>
</div>
<div class="right">
<div class="video-volume">
<i class="iconfont icon-volume"></i>
<div class="video-volume-progress">
<div class="video-volume-progress-now"></div>
<div class="video-volume-progress-bar"></div>
</div>
</div>
<div class="video-full">
<i class="iconfont icon-full"></i>
</div>
</div>
</div>
</div>
`
// 挂载播放器组件,需要判断 elm 类型,除了 as 断言,还可以使用 typeof 语法
if(typeof this.options.elm === 'object') {
this.options.elm.appendChild(this.tempContainer)
} else {
document.querySelector(this.options.elm)?.appendChild(this.tempContainer)
}
}
}
调用播放器组件
先调用popup方法创建一个弹层,然后调用 createVideo 创建播放器组件,并将其挂载到弹层中:
// src/index.ts
import popup from './components/Popup'
import createVideo from './components/Video'
popup({
width: '880px',
height: '556px',
title,
content(elm) {
createVideo({
url,
elm
})
}
})
课程收获
这节课实现了播放器组建的布局结构,其中播放控件的实现稍微复杂一些。然后在用户点击视频列表项时,调用对应的方法来唤起弹层,再创建播放器组件进行视频的播放。