在iOS微信浏览器中自动播放HTML5 audio(音乐)的2种正确方式

本文介绍如何在iOS版微信内置浏览器中实现HTML5 Audio的自动播放功能。提供了两种方法:一是使用微信JS-SDK;二是利用WeixinJSBridge。文章还探讨了不同iOS设备及微信版本间的兼容性问题。
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <title>Auto play html audio in iOS WeChat InAppBrowser the right way</title>
</head>
<body>
    <h1>在 iOS 微信浏览器中自动播放 HTML5 audio(音乐) 的正确方式</h1>
    <p>核心原理: 在微信的JS-API 中 play 一下 audio 即可达到自动播放的目的(应该是微信自己做了处理)</p>
    <br>
    <br>
    <br>
    <audio id="bgmusic" src="http://oj1hxt5z0.bkt.clouddn.com/123.mp3" autoplay preload loop controls></audio>
    <!-- 当使用方法1时必须加载 JS-SDK 的 JS 文件, 方法2不需要加载这个 JS -->
    <script src="http://res.wx.qq.com/open/js/jweixin-1.0.0.js"></script>
    <script>
    // 方法1: 现在微信官方已经推出了微信JS-SDK, 最好还是不要使用"野生"方式, 因为不知道什么时候就可以不能用了!
    // http://mp.weixin.qq.com/wiki/7/aaa137b55fb2e0456bf8dd9148dd613f.html
    // 通过config接口注入权限验证配置后, 在 ready 中 play 一下 audio
    function autoPlayAudio1() {
        wx.config({
            // 配置信息, 即使不正确也能使用 wx.ready
            debug: false,
            appId: '',
            timestamp: 1,
            nonceStr: '',
            signature: '',
            jsApiList: []
        });
        wx.ready(function() {
            document.getElementById('bgmusic').play();
        });
    }
    // 方法2: "野生"方法, 借用原来老的 WeixinJSBridge
    function autoPlayAudio2() {
        window.onload = function() {
            // alert(typeof WeixinJSBridge);
            WeixinJSBridge.invoke('getNetworkType', {}, function(e) {
                // 在这里拿到 e.err_msg, 这里面就包含了所有的网络类型
                // alert(e.err_msg);
                document.getElementById('bgmusic').play();
            });
        };
    }
    // 大家或多或少都知道 iOS Safari 不允许自动播放 audio, 可能已经被坑过了,
    // 但微信内嵌的浏览器应该是做了一些定制化, 允许自动播放 audio.
    // 测试了以下机型在微信内嵌浏览器中仅需设置 audio autoplay 即可自动播放(audio)音乐, 无需特殊处理.
    // * iPhone5     iOS 7.0.6 WeChat 6.2
    // * iPhone5s    iOS 8.1.2 WeChat 6.3.7
    // * iPhone6Plus iOS 8.1.3 WeChat 6.3.7
    // * MI1S    Android 4.1.2 WeChat 6.3.7
    // 
    // 但是当手机是 iPhone6s iOS 9.1 WeChat 6.3.7 时, 必须做如下特殊处理才能在微信中自动播放(audio)音乐,
    // 我可以推测是 iOS 9 的兼容性问题么?
    // 
    autoPlayAudio1(); // 推荐使用方法1
    // autoPlayAudio2(); // 也可以试一试方法2
    </script>
</body>
</html>

转载于:https://www.cnblogs.com/zhangkeyu/p/6657729.html

<think>我们正在处理的问题:在iOS微信浏览器中,页面跳转(例如跳转到鉴权页面)后返回,原页面可能出现的交互失效问题(如按钮点击无响应)。结合用户提供的引用和之前的问题,我们重点考虑如何恢复页面状态或保持交互能力。 引用分析: [^1]:提到在iOS微信浏览器中,如果在用户点击事件的回调函数中经历了nextTick(如异步操作),则音频无法播放。这暗示了iOS微信浏览器对异步事件处理的特殊限制。 [^2]:讨论了iOS微信中跳转APP的机制,但当前问题更关注页面内跳转后的状态恢复。 [^3]:指出iOS微信中视频、音频默认需要用户点击才能加载,自动播放需要在微信的wx.ready回调中处理。这提供了在微信环境中处理媒体自动播放的思路。 [^4]:展示了iOS App与微信小程序的交互代码,但与本问题关联不大。 核心问题:在iOS微信浏览器中,页面跳转返回后,原页面的事件监听可能失效,导致无法点击。 解决方案回顾(之前回答): 1. 使用`pageshow`事件重新绑定事件(推荐)。 2. 使用`window.onfocus`事件结合定时器重新绑定事件。 3. 检查并优化第三方库(如fastclick.js)的使用。 4. 强制刷新页面(影响体验,不推荐)。 但是,用户现在更关注的是“状态恢复”而不仅仅是事件绑定。状态恢复可能包括: - 事件监听的重新绑定(之前已解决)。 - 页面数据的恢复(例如表单数据、滚动位置等)。 - 异步操作的重新执行(如重新获取数据)。 因此,我们扩展解决方案: ### 综合解决方案:在iOS微信浏览器中处理页面跳转后的状态恢复 #### 1. 事件监听失效的恢复(基础) 使用`pageshow`事件来重新绑定事件监听器(同之前方法1): ```javascript window.addEventListener('pageshow', function(event) { if (event.persisted) { // 从缓存中恢复 // 重新绑定所有事件 reBindEvents(); } }); ``` #### 2. 页面数据恢复 由于iOS微信浏览器在返回时可能使用缓存页面(bfcache),我们可以利用`localStorage`或`sessionStorage`在页面离开前保存状态,返回后恢复。 步骤: a. 在页面跳转前(或离开前)保存关键状态: ```javascript // 在跳转发生前(例如按钮点击跳转时) document.getElementById('authButton').addEventListener('click', function() { // 保存当前表单数据或状态 const formData = { input1: document.getElementById('input1').value, // ... 其他状态 }; sessionStorage.setItem('pageState', JSON.stringify(formData)); // 然后跳转 }); ``` b. 在返回页面后,从`pageshow`事件中恢复状态: ```javascript window.addEventListener('pageshow', function(event) { if (event.persisted) { // 恢复事件绑定 reBindEvents(); // 恢复数据 const savedData = sessionStorage.getItem('pageState'); if (savedData) { const formData = JSON.parse(savedData); document.getElementById('input1').value = formData.input1; // ... 恢复其他状态 } } }); ``` #### 3. 滚动位置恢复 通常,浏览器会自动恢复滚动位置(bfcache机制的一部分)。但如果失效,可以手动保存和恢复: ```javascript // 离开页面时保存滚动位置 window.addEventListener('beforeunload', function() { sessionStorage.setItem('scrollPosition', window.scrollY); }); // 返回时恢复 window.addEventListener('pageshow', function(event) { if (event.persisted) { const scrollPosition = sessionStorage.getItem('scrollPosition'); if (scrollPosition) { window.scrollTo(0, parseInt(scrollPosition)); } } }); ``` #### 4. 异步操作重新执行 如果页面返回后需要重新获取数据(例如数据可能已过期),可以在`pageshow`事件中触发数据重新加载: ```javascript window.addEventListener('pageshow', function(event) { if (event.persisted) { // 重新加载数据 fetchData(); } }); ``` #### 5. 针对媒体元素(音频、视频)的特殊处理 参考引用[^3],在iOS微信中,媒体元素需要用户交互才能加载。因此,在返回页面后,如果希望自动播放媒体,必须将其放在微信的`wx.ready`回调中,并确保在用户交互后触发(但返回操作本身就是用户交互,所以可以尝试自动播放): ```javascript // 在pageshow事件中 if (event.persisted) { // 微信环境初始化 document.addEventListener('WeixinJSBridgeReady', function() { // 尝试播放音频/视频 const audio = document.getElementById('myAudio'); audio.play().catch(e => console.log('播放失败,可能需要用户交互')); }, false); } ``` 注意:iOS微信自动播放限制严格,可能需要用户点击后播放。但返回操作后,可以尝试在`WeixinJSBridgeReady`事件中播放。 #### 6. 避免使用可能破坏状态恢复的库 如引用[^1]所述,避免在事件回调中使用nextTick(或异步操作)来播放音频,因为这可能在iOS微信中失败。同样,在状态恢复时,避免使用可能导致延迟的异步操作。 #### 7. 强制刷新作为备选方案 如果以上方法都无效,考虑在返回时强制刷新(但会丢失页面状态): ```javascript window.addEventListener('pageshow', function(event) { if (event.persisted) { window.location.reload(); } }); ``` ### 最佳实践总结 - **事件监听**:使用事件委托(如将事件绑定到`document`或静态父元素)可以减少需要重新绑定的元素数量。 - **状态保存**:在跳转前保存关键状态,返回后恢复。 - **媒体处理**:在微信的`WeixinJSBridgeReady`事件中处理媒体播放。 - **测试**:务必在iOS微信中测试,因为模拟器可能无法完全复现问题。 通过以上步骤,可以有效地在iOS微信浏览器中恢复页面状态和交互能力。 §§相关问题§§ 1. 如何在iOS微信浏览器中保存和恢复页面状态? 2. 微信浏览器中如何实现媒体元素的自动播放? 3. 如何优化页面以兼容iOS微信浏览器的bfcache机制?</think>### iOS微信浏览器页面跳转后状态恢复与交互保持方案 在iOS微信浏览器中,页面跳转后返回时出现状态丢失或交互失效的问题,主要源于微信的页面缓存机制(bfcache)和iOS系统对WebView的特殊限制。以下是综合解决方案: --- #### 一、核心恢复机制 1. **监听页面返回事件** 使用`pageshow`事件检测页面从缓存恢复: ```javascript window.addEventListener('pageshow', function(event) { if (event.persisted) { // 确认从缓存加载 restoreState(); } }); ``` 2. **状态保存与恢复** 在跳转前保存状态,返回时恢复: ```javascript // 跳转前保存状态 function saveStateBeforeJump() { sessionStorage.setItem('pageState', JSON.stringify({ scrollPosition: window.scrollY, formData: getFormValues(), timestamp: Date.now() })); } // 返回时恢复状态 function restoreState() { const state = JSON.parse(sessionStorage.getItem('pageState') || '{}'); window.scrollTo(0, state.scrollPosition || 0); fillForm(state.formData); reBindEvents(); // 重新绑定事件 } ``` --- #### 二、事件绑定失效解决方案 1. **事件委托优化** 使用事件委托避免元素级绑定失效: ```javascript // 使用document代理点击事件 document.addEventListener('click', function(e) { if (e.target.matches('.btn-auth')) { handleAuthClick(); } }); ``` 2. **微信JS-SDK重初始化** 针对需要微信API的页面[^3]: ```javascript wx.ready(function() { wx.checkJsApi({ jsApiList: ['chooseImage'], success: function(res) { // 重新初始化微信交互组件 } }); }); ``` --- #### 三、媒体元素自动播放处理 iOS微信默认阻止媒体自动加载[^3]: ```javascript document.addEventListener('WeixinJSBridgeReady', function() { const video = document.getElementById('introVideo'); video.load(); // 手动触发加载 video.play().catch(e => console.log('播放需用户交互')); }, false); ``` --- #### 四、深度跳转兼容方案 1. **Universal Link备用跳转** 当URL Scheme被禁用时[^2]: ```html <a href="https://yourdomain.com/apple-app-site-association" style="display:none">Universal Link</a> ``` 2. **微信小程序跳转兼容** 处理小程序回调数据[^4]: ```objc // iOS端处理回调 - (void)onResp:(BaseResp *)resp { if ([resp isKindOfClass:[WXLaunchMiniProgramResp class]]) { NSString *extMsg = ((WXLaunchMiniProgramResp *)resp).extMsg; // 将数据传递回WebView } } ``` --- #### 五、终极备选方案 ```javascript // 当所有方法失效时强制刷新 if (navigator.userAgent.match(/iPhone|iPad|iPod/i)) { window.addEventListener('pageshow', (event) => { if (event.persisted && !sessionStorage.getItem('reloaded')) { sessionStorage.setItem('reloaded', 'true'); window.location.reload(); } }); } ``` > **关键注意事项**: > 1. 所有状态保存使用`sessionStorage`而非`localStorage` > 2. 避免使用`beforeunload`事件(iOS微信不保证触发) > 3. 在微信浏览器中测试时开启调试模式:`https://debugx5.qq.com` 通过组合状态保存、事件委托和微信API重初始化,可有效解决iOS微信跳转返回后的状态丢失和交互失效问题。实际部署时建议优先使用方案一 + 方案二的组合[^1][^3]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值