以下代码可能过长,请耐心查阅

前言

最近项目中有播放背景声音的一个功能,后面发现刷新浏览器后,不对页面进行任何点击操作,浏览器不播放声音。作为一个后端开发,突然搞这么一个前端解决方案是有点懵逼的,下面是和一名前端大佬讨论的结果。


解决方案:

  • 1.将提供给用户的浏览器的播放声音权限打开,然后重新打包浏览器发出去;
  • 2.给用户一个弹窗提示,点击按钮,打开浏览器声音权限或直接跳转到设置声音的页面;(经过测试发现实现不了,因为系统部署在服务端,而打开的是本地浏览器的配置,无法实现这个功能)
  • 3.置顶一个弹窗,引导用户开启声音权限,达到一劳永逸的效果。(目前博主采用)

ps:上面所说的弹窗是在浏览器刷新后,并且检测到浏览器没有开启声音的时才会弹窗。


已测试过的浏览器类型和版本:

以下浏览器做过声音测试和引导弹窗测试

  • 谷歌浏览器(版本83.0.4103.97、72.0.3626.96、65.0.3325.146)
  • 火狐浏览器(版本76.0.1 )
  • IE浏览器(版本11.836.18362.0)
  • Opera浏览器(版本68.0.3618.165)

谷歌66版本以下都支持播放,66版本以上默认拦截声音播放;IE支持声音播放,不会有提示框


静音文件和图标

这里用静音的文件去测试浏览器是否可以正常播放,图标是浏览器的图标截图,大家自己随意取

  • 链接:https://pan.baidu.com/s/1H-lrgdBtf4LamOXWfP8vbg
  • 提取码:bqxv

播放声音的标签:

  • 1.embed
  • 2.audio
<div v-if="sourceShow"><embed ref="counterfeitAudio" src="@/voice/mute.wav" autostart="false" hidden="true" v-show="false" />
</div>
<div v-else><audio ref="counterfeitAudio" controls="controls" v-show="false"><source src="@/voice/audio.wav" type="audio/wav"/></audio>
</div>

这里需要判断IE浏览器版本是否是大于9版本,如果大于9则用 embed 标签,其他浏览器和IE版本用 audio 标签。下面是IE浏览器的处理方式

//兼容ie告警声音处理if(ieVersion()>9){this.sourceShow = true}else{this.sourceShow = false}
//在app.vue导入
import {ieVersion} from "./utils/ieVersion";

/**** 判断当前浏览器是否是ie* @returns {Number}* -1代表不是ie浏览器 其他数字代表各个ie浏览器的版本*/
export function ieVersion(){let userAgent = navigator.userAgent; //取得浏览器的userAgent字符串let isIE = userAgent.indexOf("compatible") > -1 && userAgent.indexOf("MSIE") > -1; //判断是否IE<11浏览器let isEdge = userAgent.indexOf("Edge") > -1 && !isIE; //判断是否IE的Edge浏览器let isIE11 = userAgent.indexOf('Trident') > -1 && userAgent.indexOf("rv:11.0") > -1;if(isIE) {let reIE = new RegExp("MSIE (\\d+\\.\\d+);");reIE.test(userAgent);let fIEVersion = parseFloat(RegExp["$1"]);if(fIEVersion == 7) {return 7;} else if(fIEVersion == 8) {return 8;} else if(fIEVersion == 9) {return 9;} else if(fIEVersion == 10) {return 10;} else {return 6;//IE版本<=7}   } else if(isEdge) {return 'edge';//edge} else if(isIE11) {return 11; //IE11}else{return -1;//不是ie浏览器}
}

方案代码:

1.在app.vue里面引入组件

这里是 voiceShow 是当用户登录过期或在其他情况时关闭提示框用

<template><div id="app" class="appCss"><voice :voiceShow="voiceShow"/></div>
</template>
import voice from '@/components/voice/index'
export default {name: 'App',components: {voice},data() {return {voiceShow: false}},methods:{closeDialog(){// 关闭引导用户开启浏览器声音播放权限的提示框this.voiceShow = false;}}
}

2.引导用户的对话框:voice.vue
<template><el-dialogtitle="提示":visible.sync="dialogVisible"width="30%":close-on-click-modal="false":close-on-press-escape="false"class="voiceTips"><span><p>系统检测到当前浏览器未开启背景声音播放权限,请前往浏览器设置开启<br/>步骤如下:<br/>&nbsp;</p></span><span v-if="browserInfo.type === 'IE'"><p>1.点击右上角的 <img src="@/voice/tipImg/IE.png"/> 图标,再选择 "Internet 选项"<br/>2.选择 "高级",在设置一栏中往下拉,找到 "多媒体",再勾选 "在网页中播放声音",点击确定<br/>3.重启计算机即可</p></span><span v-else-if="browserInfo.type === 'Firefox'"><p>1.点击右上角的 <img src="@/voice/tipImg/Firefox.png"/> 图标,再选择 "选项"<br/>2.选择左侧 "隐私与安全",再下拉找到权限一栏,点击 "自动播放" 的设置按钮<br/>3."所有网站的默认值" 设置为 "允许音频和视频",再点击 "保存更改"<br/>4.返回当前页面即可</p></span><span v-else-if="browserInfo.type === 'Chrome'"><p>1.点击左上角网址前面的 <img src="@/voice/tipImg/Chrome.png"/> 图标,再点击 "网站设置"<br/>2.找到 "声音" 一栏,选择 "允许"<br/>3.返回当前页面,点击浏览器上方提示的 "重新加载" 按钮即可</p></span><span v-else-if="browserInfo.type === 'Opera'"><p>1.点击左上角网址前面的 <img src="@/voice/tipImg/Opera.png"/> 图标,再点击 "网站设置"<br/>2.找到 "声音" 一栏,选择 "允许"<br/>3.返回当前页面,点击浏览器上方提示的 "重新加载" 按钮即可</p></span><span v-else-if="browserInfo.type === 'Safari'"><p>1.打开浏览器的设置,找到声音设置,选择允许声音播放<br/>2.返回当前页面即可</p></span><span v-else><p>1.打开浏览器的设置,找到声音设置,选择允许声音播放<br/>2.返回当前页面即可</p></span><span slot="footer" class="dialog-footer"><el-button type="primary" @click="dialogVisible = false" style="text-align: center;">确 定</el-button></span></el-dialog>
</template><script>import {getBrowserInfo, checkAutoPlay} from '@/utils/checkAudio'export default {name: "voice",props: ['voiceShow'],watch: {$route: {//监听路由变化handler: function (val, oldVal) {this.dialogVisible = this.voiceShow;},immediate: true,deep: true},},data() {return {title: '声音检测',dialogVisible: false,//获取浏览器的详细信息browserInfo:{}}},methods:{// 检测浏览器类型async getBrowserInfoFun(){let info = await getBrowserInfo();this.$nextTick(()=>{this.browserInfo = info;});},// 检测声音能否播放async checkAutoPlayFun(){// 检测当前流量器是否能自动播放背景声音let autoplay = await checkAutoPlay();if(autoplay === false){this.dialogVisible = true;}},},created(){},mounted() {const that = this;// 监听浏览器刷新事件,用户为登录状态,且不在登录页时才弹出提示let fullPath = that.$router.currentRoute.fullPath;if(that.$store.getters.isLogin === 'true' || that.$store.getters.isLogin === true){if(fullPath !== '/' && fullPath !== '/login'){that.getBrowserInfoFun();that.checkAutoPlayFun();}}}}
</script><style lang="scss">.voiceTips{margin-top: 93px;z-index: 9999!important;}
</style>

3.检测声音和浏览器类型和版本:checkAudio.js
/*** 获取浏览器类型和版本号*/
export function getBrowserInfo (){const agent = navigator.userAgent.toLowerCase();const regStr_ie = /msie [\d.]+;/gi ;const regStr_ff = /firefox\/[\d.]+/giconst regStr_chrome = /chrome\/[\d.]+/gi ;const regStr_saf = /safari\/[\d.]+/gi ;const regStr_opera = /opr\/[\d.]+/gi ;//ieif (agent.indexOf("msie") >= 0) {const ver= agent.match(regStr_ie)[0];return {type:"IE",version:ver.replace(/[^0-9.]/ig,"")};}//firefoxelse if (agent.indexOf("firefox") >= 0) {const ver=agent.match(regStr_ff)[0];return {type:"Firefox",version:ver.replace(/[^0-9.]/ig,"")};}//Operaelse if(agent.indexOf("opr") >= 0){const ver=agent.match(regStr_opera)[0];return {type:"Opera",version:ver.replace(/[^0-9.]/ig,"")};}//Chromeelse if(agent.indexOf("chrome") >= 0){const ver=agent.match(regStr_chrome)[0];return {type:"Chrome",version:ver.replace(/[^0-9.]/ig,"")};}//Safarielse if(agent.indexOf("Safari") >= 0){const ver=agent.match(regStr_saf)[0];return {type:"Safari",version:ver.replace(/[^0-9.]/ig,"")};}
}/*** 检测浏览器是否支持自动播放!* return @Promise boolean*/
export function checkAutoPlay(){// 返回一个promise以告诉调用者检测结果return new Promise(resolve => {const audio = document.createElement('audio');// require一个本地文件,会变成base64格式,这里用的是没有声音的文件进行检测的audio.src = require('@/voice/mute.wav');document.body.appendChild(audio);let autoplay = true;// play返回的是一个promise// audio.volume = 0;audio.play().then(() => {// 支持自动播放autoplay = true;}).catch(() => {// 不支持自动播放autoplay = false;}).finally(() => {audio.remove();// 告诉调用者结果resolve(autoplay);});});
}

自此已将全部逻辑写完,希望对大家有用


参考网址:https://juejin.im/post/5af7129bf265da0b8262df4c.

刷新浏览器后不进行任何点击操作时,不播放声音 | 解决方案(VUE-Element)相关推荐

  1. vuex状态持久化:vuex-persistedstate解决刷新浏览器后vuex状态重置问题

    一.问题和原因 问题和现象:刷新浏览器后vuex状态重置 原因:vuex将数据保存在cache(运行内存)中,内存中的数据是临时数据,刷新浏览器就会释放.类似于js创建一个变量,刷新浏览器变量会销毁, ...

  2. vue中如何点击返回上一页,vue判断没有上页返回首页

    vue中如何点击返回上一页,vue判断没有上页返回首页 vue中返回上一页 // 返回 returnBtn(){this.$router.go(-1); }, 返回上一页,先判断是否有上一页,没有则返 ...

  3. 设备管理器点击操作时只有帮助选项

    在做硬件驱动测试的时候,打开设备管理器,点击操作只有帮助选项而没有添加过时硬件等选项,只需要随便点击一下下面的设备(处理器,打印队列等),就可以返回继续操作了.图例,上面的图只有帮助,下面则会有其他的 ...

  4. Vue.JS项目中二级路由下刷新浏览器仍呈现当前路由的实现方案

    1.需求介绍: 以下介绍一下实现起来没什么疑问的需求:设备列表为一个主页,点击设备列表中的编辑按钮,进入设备信息主页面,默认打开设备配置页,点击设备状态.设备日志.固件升级,会切换下方内容. 本人对以 ...

  5. CAD图纸编辑完成后保存成PDF格式怎么操作?

    平时在我们对CAD图纸的绘制过程中,经常需要对CAD图纸的格式进行转换,因为CAD格式的图纸在一般常见的看图软件中是无法打开的,需要在特定的环境中才可以打开,这就需要我们在图纸绘制完成后保存为易于查看 ...

  6. 超级管理员登陆后如果连续20分钟无操作再次操作时需要重新登陆的思路

    这个可以采用session"垃圾回收机制"实现, 可以设置时间限制,在这路设置二十分钟后,当未进行页面操作时触发这个回收机制,连续20分钟未操作之后,对于登陆记录进行销毁,销毁后进 ...

  7. 如何点击按钮弹出新窗口,输入数据后返回并刷新页面

    如何点击按钮弹出新窗口,输入数据后返回并刷新页面? 作者:孟宪会 出自:[孟宪会之精彩世界] 发布日期:2003年7月8日 4点0分13秒 在一些.NET论坛中有人经常会问:如何在页面中点击按钮打开新 ...

  8. 浏览器 刷新页面后回到顶部_当你在浏览器中,忘记了曾经的登录密码怎么办......

    当你在浏览器中,忘记了曾经的登录密码怎么办... 前言 你还在为使用浏览器的时候,忘记密码而烦恼吗?今天要分享的不为人知的小技巧,利用前端技术原理来帮助你找回原密码. 在我们使用各种网站登录时,总会勾 ...

  9. 前端js控制点击切换效果且刷新浏览器不会重置

    提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言 一.布局的部分代码和样式 二.使用js来控制点击时颜色变化,点击哪一个图标,哪一个图标就应该变橙色且带有下边框 1.分 ...

最新文章

  1. OpenCV再升级!修改一行代码,将图像匹配效果提升14%!
  2. # 2021华为软件精英挑战赛C/C++——build.sh/build_and_run.sh/CodeCraft_zip.sh注释
  3. 文曲星猜数游戏,无测试代码
  4. oracle xtts 介绍,oracle_rman_xtts_v3
  5. linux下Eclipse+CDT开发环境配置与使用
  6. 安装mysql冲突_Linux下安装mysql版本冲突问题解决
  7. php网页制作 博客,php响应式的个人博客网站设计
  8. 机器数,原码,反码,补码,移码
  9. JAVA操作属性文件,可进行读 写 更改
  10. idea修改完jdbc文件后没有更新_JDBC+MySQL入门案例
  11. (21)FPGA面试技能提升篇(JESD204B接口)
  12. regsvr32.exe进程注册dll文件
  13. 关于Windows 2003 sp1不能打开CHM文件的问题
  14. 关于Windows 1803版本内核隔离打开后无法关闭的解决方案
  15. PHP try catch 捕获异常,最后调用的方法中错误不打印
  16. 小学计算机专业说课稿模板,小学信息技术说课稿模板汇总八篇
  17. 百度2014校园招聘-研发工程师笔试题(济南站)
  18. 红米k40pro一键root教程
  19. 当前读和快照读的区别
  20. 数分下第11讲(9.5节) 多变量函数的Taylor公式与极值

热门文章

  1. 小白投资理财必看:图解基金买入与卖出规则
  2. 网络安全特训之——网络信息安全攻防学习平台(基础关)
  3. 外包模式下的精益敏捷开发 (人员能力篇)
  4. VUE中created被重复调用(每次进入页面之后都会调用created)
  5. SpringMVC ResponseBody返回字符串带双引号解决
  6. 【DFS专题训练】王子救公主 C++程序题
  7. Presto中broadcast join和partition join执行计划的处理过程
  8. C/C++中的ctime用法总结
  9. 其他|Cherry 键盘 Fn 锁定切换方法
  10. python可以用else作为变量名_在Python中可以使用if作为变量名。