由为学姐庆祝生日所想到的——网站背景音乐播放

事件起因

在为漂亮姐姐写庆祝生日的网站时,想添加一段背景音乐烘托气氛,但是发现仅仅使用js来控制背景音乐触发没用,会报错,报错原因如下

Uncaught (in promise) DOMException: play() failed because the user didn't interact with the document first.

检索发现是因为浏览器禁止在用户不交互时触发音乐视频等,所以搜索了半天,最后还是才有业内比较常见的交互式触发。

固定按钮触发

用绝对定位在右上角添加一个固定按钮,通过点击按钮来控制音乐的暂停和播放。代码逻辑是通过js代码控制图片的切换来反映音乐的播放和暂停的状态

实现步骤:

  1. HTML 结构:创建一个按钮元素,用于用户点击切换播放和暂停。
  2. CSS 样式:定义按钮的基本样式,以及播放和暂停状态下的不同背景图片。
  3. 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,很怀疑是不是为了故意让用户交互而设置。不知道米哈游是搞了什么奇怪的黑科技,同样有音乐按钮

ys.mihoyo.com/

ys.mihoyo.com/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)

相关推荐
undefined&&懒洋洋13 分钟前
Web和UE5像素流送、通信教程
前端·ue5
大前端爱好者2 小时前
React 19 新特性详解
前端
随云6322 小时前
WebGL编程指南之着色器语言GLSL ES(入门GLSL ES这篇就够了)
前端·webgl
随云6322 小时前
WebGL编程指南之进入三维世界
前端·webgl
寻找09之夏3 小时前
【Vue3实战】:用导航守卫拦截未保存的编辑,提升用户体验
前端·vue.js
多多米10054 小时前
初学Vue(2)
前端·javascript·vue.js
柏箱4 小时前
PHP基本语法总结
开发语言·前端·html·php
新缸中之脑4 小时前
Llama 3.2 安卓手机安装教程
前端·人工智能·算法
hmz8564 小时前
最新网课搜题答案查询小程序源码/题库多接口微信小程序源码+自带流量主
前端·微信小程序·小程序
看到请催我学习4 小时前
内存缓存和硬盘缓存
开发语言·前端·javascript·vue.js·缓存·ecmascript