触屏RIA开发之为zepto升级,模拟用户行为

首先,老习惯,先介绍背景:

  在开发html5的音乐播放RIA时,在Ios的safari里本小姐发现了一个诡异的问题:

1 //代码前提是引用了zepto.js
2 var audio = $("audio")[0];
3 audio.src="test.mp3";
4 audio.bind("tap",function(e){
5         audio.play();
6 })

  zepto的tap居然失效了!!!怎么回事呢?加了很多断点后,发现tap事件并没有失效,而是在tap的回调函数里的audio.play()失效了,android的chrome啊,uc啊,还有PC端都是没有问题的,唯独safari,T^T,郁闷啊。。。。仔细研究了zepto的源码,发现zepto中所有事件,都运用了跳出线程的setTimeout函数。那么,就有了如下猜测:

  由于有setTimeout的关系,浏览器将这个事件的触发看做了js代码行为,而不是用户行为,而对于HTML5的媒体标签(<audio><video>)safari有诡异的安全限制:不是用户的直接行为环境下,不能调用媒体标签的API。如果这个假设成立,那么直接绑定touchend事件,audio.play()应该可以执行。

     接下来的验证,证明了本小姐的推测~那么,怎么解决这个问题呢。

     那就是,为zepto升级,模拟用户行为:

  大概思路就是,当用户触发一个事件的时候,我们创建一个dom对象,并为他绑定个事件,并模拟用户的方式触发这个事件。

  铛铛铛铛~~~~代码如下:

复制代码
 1 function simuEvent(callback) {
 2     var a = document.createElement('A');
 3     a.on('click',function handler(e) {
 4         this.off('click', handler);
 5         callback();
 6     }, false);
 7     var e = document.createEvent('MouseEvent');
 8     e.initMouseEvent('click', true, true, this, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
 9     a.dispatchEvent(e);
10 }
复制代码

  那么如何使用呢?

  如果需要绑定和媒体标签的API有关的事件,在绑定事件时,回调函数中使用就可以了,最初的代码修改如下:

1 //代码前提是引用了zepto.js
2 var audio = $("audio")[0];
3 audio.src="test.mp3";
4 audio.bind("tap",function(e){
5          simuEvent(function(e2){ 
6                audio.play(); 
7           });
8 })

这下,就可以绕过safari诡异的安全机制了,欺骗了傻乎乎的浏览器,哈哈。

posted @   毛绒猫猫  阅读(1310)  评论(0编辑  收藏  举报
编辑推荐:
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
阅读排行:
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 周边上新:园子的第一款马克杯温暖上架
点击右上角即可分享
微信分享提示