使用h5新特性,轻松监听任何App自带返回键(最新版)

1、前言

如今h5新特性、新标签、新规范等有很多,而且正在不断完善中,各大浏览器商对它们的支持,也是相当给力。作为前端程序员,我觉得我们还是有必要积极关注并勇敢地加以实践。接下来我将和各位分享一个特别好用的h5新特性(目前也不是特别新),轻松监听任何App自带的返回键,包括安卓机里的物理返回键,从而实现项目开发中进一步的需求。

2、起因

大概半年前接到pm这需求,用纯h5实现多audio的播放、暂停、续播,页面放至驾考宝典App中,与客户端没有任何的交互,换言之就是混合型开发,功能型h5。所以与客户端相关的js不需要引用。那为什么不让客户端实现让前端h5实现?更何况App里的返回键还是原生的,ios和安卓里的双方协议可能还不一样。这是我撸码之前提出的疑问。pm小姐姐回我客户端还得发版、审核,太麻烦了,h5一个线上链接就搞定了。好吧,既然是这样,看上去这需求也挺简单的嘛,虽然之前也没做过类似的需求。不管三七二十一,撸起袖子就是干,开始了填坑之旅。

3、具体页面展示

clipboard.png

clipboard.png

这就是设计稿及最终成稿图了。用户点击任何一个图标都可以实现音频的播放,而且点击的同时图标会发生变化,再点击相同图标即可实现暂停,以此类推。当第一个音频正在播放时,点击其他图标,第一个音频会自动暂停,以此类推。我相信做过类似需求的朋友,应该会很熟悉产品到底希望我们前端做成什么样。所以,这里会有几个坑,不仅仅是监听App的返回键。我先说第一个。

第一: 播放音频时,需要秒开,而不是等待一秒甚至更长时间。由于产品最开始给我的是本地音频文件,当时我也没考虑到线上音频文件(这样加载也许会更快但也许也会更慢),因为audio默认加载模式是先下载完,当音频就绪后再播放。所以最后我采取预加载模式,提高加载效率,尽可能让用户感受不到有延迟的存在。代码如下:

clipboard.png

这样即可。但这只规避了第一个坑。第二个坑或可以称之为自主优化,即播放进度条的时刻显示和暂停了。需求里是没有播放进度条的,但在需求上线后我和pm小姐姐沟通的过程中,对方肯定、称赞了我的设计。播放进度条的设计和增加,更接近原生App、用户体验也更好。以及页面初始化时,菊花图的存在,也很有意义。自定义播放进度条,根据当前播放的音频时长而变化,该暂停就暂停,该重新初始化就重新初始化,很好的融合进页面。希望这点也帮助到大家。而涉及的代码,具体会用到canplay、timeupdate事件,以及load()函数等。此处我个人用jq实现的。

clipboard.png

第二、DOM结构的渲染。非常不推荐在页面里写死,六个较少,勉强可以这么写。但是一旦数量增加,非常不可取。我最开始用的是传统的字符串拼接实现,但后来我导师建议我用模板引擎渲染,而驾考宝典事业部默认用artTemplate.js,最后我便修改了下。它分为原生JS和jq两个版本写法,各位也可自行研究下————模板引擎和拼接字符串的优缺点。如果自行设计一个模板引擎,该如何设计。

4、接下来着重介绍下我具体是怎么监听任何App自带的返回键,以及安卓机里的物理返回键。

那为什么我要去监听呢,这里我有必要强调强调再强调。苹果手机不管是微信、QQ、App,还是浏览器里,涉及到audio、video,返回上一页系统会自动暂停当前的播放的,但不是所有安卓机都可以。所以我们自己必须自定义监听。很多朋友可能第一想法就是百度,然后出来的答案无非是这样

pushHistory(); 
window.addEventListener("popstate", function(e) { 
    alert("我监听到了浏览器的返回按钮事件啦");//根据自己的需求实现自己的功能 
}, false); 
function pushHistory() { 
    var state = { 
        title: "title", 
        url: "#"
    }; 
    window.history.pushState(state, "title", "#"); 
}

是不是很眼熟?然而关键需求不能完美实现,要这段代码有何用,当时我也是绞尽脑汁。直到经过大神好友指导,复制了这段代码

var hiddenProperty = 'hidden' in document ? 'hidden' :    
    'webkitHidden' in document ? 'webkitHidden' :    
    'mozHidden' in document ? 'mozHidden' :    
    null;
var visibilityChangeEvent = hiddenProperty.replace(/hidden/i, 'visibilitychange');
var onVisibilityChange = function(){
    if (document[hiddenProperty]) {    
        console.log('页面非激活');
    }else{
        console.log('页面激活')
    }
}
document.addEventListener(visibilityChangeEvent, onVisibilityChange);

所有问题迎刃而解。
这段代码的原理我个人理解就是通过判断用户浏览的是否为当前页,从而进行相关操作。
这是 MDN相关链接: https://developer.mozilla.org...

所以最后我是这么处理的,代码截图如下:

clipboard.png

5、手机兼容性

众所周知现在的安卓机系统4.0等都是低配版了,该属性大部分安卓机都能识别,个人低配版安卓机无法识别,原因在于navigator.userAgent内核版本过低,chrome现在很多是64+了,所以遇到该问题只要想办法兼容它就好了。

综上,遇到这个问题各位也不要过度担心,办法肯定是有的,但不是一根筋,而是通过转变思路,快速实现需求。希望这个特性能帮到大家。

6、感谢及呼吁

自从18年3月我公开发表了这篇文章,当时写的很简洁,但阅读量还是有不少,我挺吃惊的,谢谢各位的认可。但随后包括直到今天,我发现有不少知名微信公众号和网站都转载了我的这篇文章,有些并没有标明原文地址和作者,这让我也很意外和失望。所以最后希望大家能互相尊重吧,最终每个人的劳动成果,谢谢。在转载文章时,标注真实的原文地址和作者。这也是为什么我这次要更新文章的原因。另外,现在我已经不做常规的业务开发,本人已转投h5游戏开发,集游戏创意、美术、编码、测试于一身,欢迎同道朋友交流哦。

阅读 8.9k

推荐阅读
WckY
用户专栏

以文科生角度 思维 和各位分享理工男的世界

17 人关注
4 篇文章
专栏主页