题目形貌
最近在开辟一个视频播放器项目,须要隐蔽 video 标签,运用 canvas 本身做衬着。效果在点按钮播放视频的时刻发明 zepto touch 模块不能用了。
调试效果
看了一下毛病提醒,发明手机浏览器只允许用户操纵翻开 video,换句话说不论你最终是哪一个函数实行了 video.play(),你的挪用栈上溯到最最先一定是一个 DOM 元素的 UI 事宜回调。
然则zepto touch 模块是这么封装 tap 事宜的:
tapTimeout = setTimeout(function() {
// trigger universal 'tap' with the option to cancelTouch()
// (cancelTouch cancels processing of single vs double taps for faster 'tap' response)
var event = $.Event('tap')
event.cancelTouch = cancelAll
// [by paper] fix -> "TypeError: 'undefined' is not an object (evaluating 'touch.el.trigger'), when double tap
if (touch.el) touch.el.trigger(event)
// trigger double tap immediately
if (touch.isDoubleTap) {
if (touch.el) touch.el.trigger('doubleTap')
touch = {}
}
// trigger single tap after 250ms of inactivity
else {
touchTimeout = setTimeout(function(){
touchTimeout = null
if (touch.el) touch.el.trigger('singleTap')
touch = {}
}, 250)
}
}, 0)
运用 setTimeout 异步实行函数,致使挪用栈被清空了,体系推断的时刻天然不会认为是用户操纵致使的 video.play()。
修正计划
那末比较粗犷的解决方法就是修正 zepto 代码,把 tap 事宜的引发行动从异步回调中移出来同步实行,详细的说就是这三行:
var event = $.Event('tap')
event.cancelTouch = cancelAll
if (touch.el) touch.el.trigger(event)
由于 tap 事宜是没有什么延时的,所以直接移出来不会有什么影响,如果是延时事宜就很为难了,临时还想不出来什么解决方法。