cssaudio碟⽚样式,关于Audio⾃定义样式
前置
关于 css 来设置 audio 样式
关于 JavaScript 来设置样式
关于 React 写⼀个⾃定义的 Audio 组件
总结
前置⼤致了解 audio 属性
懂⼀点点 CSS
懂⼀点点 JS 与 audio 事件
懂⼀点点 React
关于 css 来设置 audio 样式audio 元素没有⾃带的固有视觉样式,除⾮如果声明了 controls 属性,则会显⽰浏览器的默认控件。
默认控件的 display 的默认值为 inline。将该值设为 block 通常会对定位和布局有好处,除⾮你想将控件放在⽂本块或类似元素中。好看的css代码
你可以使⽤作⽤于整个控件的属性来为其设置样式。例如可⽤ border、border-radius、padding, margin 等等。但你不能设置⾳频播放器中的单个组件(如改变按钮⼤⼩、改变图标或字体等)。控件在不同的浏览器中也有所不同。
如果在跨浏览器中得到⼀致的外观和体验,你需要创建⾃定义控件;⾃定义控件可以根据你的需求任意设置样式,还可以使⽤ JavaScript 和 HTMLMediaElement API 来设置更多功能。
视频播放器样式基础 提供了⼀些有⽤的样式技术,这篇⽂章围绕 video ⽽写,但⼤部分都可以⽤于 audio。
总上所述,关键就是在于 css 可操作性相对少,且会产⽣关于兼容性的问题
关于 JavaScript 来设置 audio 样式
说是 JavaScript ,依然也需要配合到 css ⾥⾯来的(不然不好看准备⼀个,最简单的带有 audio 的 html,并把布置好布局
关键 JavaScript 代码2.1 准备参数
2.2 播放 && 暂停 && 进度更新
2.3 拖动进度条
配合 css ⾷⽤
准备⼀个,最简单的带有 audio 的 html,并把布置好布局
Audio DIY
id='audio'
src='illa/media/cc0-audio/t-rex-roar.mp3''
preload='metadata' >
播放
00:00 / 00:00
2.1 准备参数const Audio = document.querySelector('#audio');
const contorl = document.querySelector('#control');
const contorlDot = document.querySelector('#control-dot');
const contorlProgress = document.querySelector('#control-progress'); const contorlProgressBox = document.querySelector('#progress'); const current = document.querySelector('#current');
const duration = document.querySelector('#duration');
// ⼯具函数
// 时分秒转换
function transTime(value) {
var time = '';
var h = parseInt(`${value / 3600}`);
value %= 3600;
var m = parseInt(`${value / 60}`);
var s = parseInt(`${value % 60}`);
if (h > 0) {
time = formatTime(h + ':' + m + ':' + s);
} else {
time = formatTime(m + ':' + s);
}
return time;
}
// 补零
function formatTime(value) {
var time = '';
var s = value.split(':');
var i = 0;
for (; i < s.length - 1; i++) {
time += s[i].length === 1 ? '0' + s[i] : s[i];
time += ':';
}
time += s[i].length === 1 ? '0' + s[i] : s[i];
return time;
}
2.2 播放 && 暂停 && 进度更新contorl.addEventListener('click', e => {
if (e.target.innerText === '播放') {
e.target.innerText = '暂停';
Audio.play();
} else {
e.target.innerText = '播放';
Audio.pause();
}
});
Audio.addEventListener('loadedmetadata', e => {
duration.innerText = transTime(e.target.duration);
});
Audio.addEventListener('timeupdate', e => {
let value = e.target.currentTime / Audio.duration;
current.innerText = transTime(e.target.currentTime); contorlProgress.style.width = `${value * 100}%`; contorlDot.style.left = `${value * 100}%`;
});
Audio.addEventListener('ended', e => {
contorlProgress.style.width = '0%';
contorlDot.style.left = '0%';
contorl.innerText = '播放';
});
2.3 拖动进度条// ⿏标按下
contorlDot.addEventListener('mousedown', down, false); contorlDot.addEventListener('touchstart', down, false);
// 开始拖动
document.addEventListener('mousemove', move, false); document.addEventListener('touchmove', move, false);
// 拖动结束
document.addEventListener('mouseup', end, false); document.addEventListener('touchend', end, false);
const position = {
oriOffestLeft : 0, // 移动开始时进度条的点距离进度条的偏移值oriX : 0, // 移动开始时的x坐标
maxLeft : 0, // 向左最⼤可拖动距离
maxRight : 0, // 向右最⼤可拖动距离
let flag = false; // 标记是否拖动开始
const down = event => {
if (!Audio.pause || Audio.currentTime !== 0) {
flag = true;
event.clientX;
// 要同时适配mousedown和touchstart事件
position.maxLeft = iOffestLeft;
// 向左最⼤可拖动距离
position.maxRight = contorlProgressBox.offsetWidth -
if (event && event.preventDefault) event.preventDefault();
urnValue = false;
if (event && event.stopPropagation) event.stopPropagation();
else window.event.cancelBubble = true;
}
};
const move = event => {
if (flag) {
let clientX = uches ? uches[0].clientX : event.clientX;
let length = clientX - iX;
if (length > position.maxRight) {
length = position.maxRight;
} else if (length < -position.maxLeft) {
length = -position.maxLeft;
}
let pgsWidth = parseFloat(
let rate = (iOffestLeft + length) / pgsWidth;
Audio.currentTime = Audio.duration * rate;
};
const end = () => {
flag = false;
};
关于 React 写⼀个⾃定义的 Audio 组件
框架加持会让组件更加简单,这⾥加⼊了 TSimport React, { useRef,
useLayoutEffect,
useState,
useEffect,
MouseEvent,
} from 'react';
import './Audio.css';
function transTime(value: number) {
var time = '';
var h = parseInt(`${value / 3600}`);
value %= 3600;
var m = parseInt(`${value / 60}`);
var s = parseInt(`${value % 60}`);
if (h > 0) {
time = formatTime(h + ':' + m + ':' + s);
} else {
time = formatTime(m + ':' + s);
}
return time;
}
function formatTime(value: string) {
var time = '';
var s = value.split(':');
var i = 0;
for (; i < s.length - 1; i++) {
time += s[i].length === 1 ? '0' + s[i] : s[i];
time += ':';