事件起因
在为漂亮姐姐写庆祝生日的网站时,想添加一段背景音乐烘托气氛,但是发现仅仅使用js来控制背景音乐触发没用,会报错,报错原因如下
Uncaught (in promise) DOMException: play() failed because the user didn't interact with the document first.
检索发现是因为浏览器禁止在用户不交互时触发音乐视频等,所以搜索了半天,最后还是才有业内比较常见的交互式触发。
固定按钮触发
用绝对定位在右上角添加一个固定按钮,通过点击按钮来控制音乐的暂停和播放。代码逻辑是通过js代码控制图片的切换来反映音乐的播放和暂停的状态
实现步骤:
- HTML 结构:创建一个按钮元素,用于用户点击切换播放和暂停。
- CSS 样式:定义按钮的基本样式,以及播放和暂停状态下的不同背景图片。
- JavaScript 逻辑:编写脚本来处理点击事件,切换播放和暂停状态,并更新按钮的样式。
HTML
bash
<button id="playPauseButton" class="play-pause"></button>
CSS
css
.play-pause {
width: 50px;
height: 50px;
background-size: contain;
background-repeat: no-repeat;
background-image: url("../svg/播放.svg");
border: none;
cursor: pointer;
}
.play-pause.playing {
background-image: url("../svg/暂停.svg");
}
JavaScript/TypeScript
ini
const playPauseButton = document.getElementById('playPauseButton');
let isPlaying = false; // 初始状态为未播放
playPauseButton.addEventListener('click', () => {
isPlaying = !isPlaying; // 切换播放状态
if (isPlaying) {
// 如果当前是播放状态,则开始播放音频并更新按钮样式
audio.play();
playPauseButton.classList.add('playing');
} else {
// 如果当前是暂停状态,则暂停音频并更新按钮样式
audio.pause();
playPauseButton.classList.remove('playing');
}
});
这样,当点击按钮时,isPlaying
变量的状态会切换。根据这个状态,脚本会控制音频的播放或暂停,并且切换按钮的 CSS 类以更新背景图片。
切换实现效果如下
添加一点小旋转
当然,播放时最好设置一个图片的旋转,可以使用css的动画帧
具体来说,可以创建一个 @keyframes
动画,它定义了从开始到结束的动画过程,然后将这个动画应用到图标元素上。
CSS
首先,定义一个 @keyframes
规则来描述旋转动作:
css
@keyframes rotate {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}
然后,将这个动画应用到你想要旋转的元素上。例如,如果你想让 .play-pause
类的元素旋转:
css
.play-pause {
animation: rotate 2s linear infinite;
/* 其他样式 */
}
在这个例子中,动画名称是 rotate
,它将在 2 秒内从 0 度旋转到 360 度,并且会无限次重复。linear
表示动画的速度在其整个持续时间内保持不变。
其它业内方案
闲的没事还同时考察了一些其它网页的音乐播放设置。发现业内在该方面还是有一些不同的解决方案。
如原神的官网中,他就默认实现了自动播放音乐,但是很奇怪的是需要从首页进入main页才能播放音频,而直接进入main是播放不了的,同时浏览器搜索只能搜出首页,搜不到main,很怀疑是不是为了故意让用户交互而设置。不知道米哈游是搞了什么奇怪的黑科技,同样有音乐按钮
在腾讯的白荆回廊中,它是使用的是全局点击捕捉(我觉得有点奇怪的),对全局的按钮点击进行捕获,这让我想起了js的冒泡事件,对冒泡事件的捕获。似乎在window上加的事件监听,对功能性按钮的点击会往上冒泡到最顶层的全局事件------音乐播放。同时没有音乐按钮。
白荆回廊-官方网站「于世界交点之处,逢似曾相识之人」 (qq.com)
原理探讨
developer.mozilla.org/zh-CN/docs/...
核心逻辑在mdn的文章中已经讲的很清楚了。小结一下就是通常浏览器会提供各种方式禁用自动播放音频功能,但是有以下例外:
- 音频被静音或其音量设置为 0
- 用户和网页已有交互行为(包括点击、触摸、按下某个键等等)
- 网站已被列入白名单;如果浏览器确定用户经常与媒体互动,这可能会自动发生,也可能通过首选项或其他用户界面功能手动发生
- 自动播放权限策略被应用于
<iframe>
或者其文档上,从而获得了自动播放的权限。
普遍采用的是第二种交互行为方案。同时除js设置触发外,也可通过autoplay属性触发自动播放。如下
ini
<audio id="musicplayer" autoplay>
<source src="/music/chapter1.mp4" />
</audio>
综上,真是学无止境,随便写点小网站也能发现这么多的背后知识,真是学海无涯。 最后贴一下项目的Github地址,求Star:abandon888/happy-birthday: 简约的生日祝福网站,可用于表白和祝福特别的人 (github.com)