android 点击事件失效,iScroll5 安卓手机点击事件失效

一、测试平台

三星 i9023 android 4.1.2 (正常)

三星 i9250 android 4.2.2 (存在问题)

三星 i9300 android4.1.1 (存在问题)

三星 i9308 android 4.0.4 (存在问题)

二、问题描述

上述手机出现无法滑动或者无法触发点击事件的情况

三、问题分析

1、onBeforeScrollStart方法

onBeforeScrollStart: function (e) { e.preventDefault(); }

此方法是在_start里进行了调用,目的是为了阻止浏览器默认动作的执行,防止在滑动的过程中进行干扰,同时也就阻止了滑动区域里元素的事件的触发,这种处理方式也直接导致了必须要在_end方法中再次触发元素的点击事件

2、_end方法

if(target.tagName != ‘SELECT‘ && target.tagName != ‘INPUT‘&& target.tagName != ‘TEXTAREA‘) {

ev= document.createEvent(‘MouseEvents‘);

ev.initMouseEvent(‘click‘,true,true,

e.view,1,point.screenX,

point.screenY, point.clientX,

point.clientY,e.ctrlKey,

e.altKey, e.shiftKey,

e.metaKey,0,null);

ev._fake=true;

target.dispatchEvent(ev);

}

这个处理方式就是顺承了上面所提到的阻止了浏览器默认行为后,对滑动区域除SELECT、INPUT、TEXTAREA外的元素触发click事件,已完成对click绑定事件的调用。

【具体分析】

由于onBeforeScrollStart是在_start方法中进行的调用,e.preventDefault();阻止了元素的默认行为,从而导致了元素绑定事件的失效,必须在_end操作结束后进行绑定事件的模拟调用,原始的iScroll源代码中在_end中最后创建了click事件的模拟,但是这里必须要清楚的一个原理就是,click其实是要依赖于其他事件的:

1) 普通pc网页中,click需要依赖于mousedown、mouseup的相继触发

2) 移动webkit中,click则需要依赖于touchstart、touchend(实际mousedown,mouseup在移动webkit上也存在)的相继触发

“相继触发”的意思就是中间不会夹杂有其他的事件类型,这也就很容易理解iScroll中在_end中对模拟事件调用的条件了,必须要判断that.moved才能直接触

发模拟事件。

iScroll中与_start、_move、_end相关的三个事件类型是按照如下的规则来设置的:

START_EV = hasTouch ? ‘touchstart‘ : ‘mousedown‘MOVE_EV= hasTouch ? ‘touchmove‘ : ‘mousemove‘END_EV= hasTouch ? ‘touchend‘ : ‘mouseup‘

【注意事项】

经测试,三星部分手机里默认浏览器里会默认所有元素都有一个默认的click事件(测试结果显示鼠标事件中默认事件包含mouseup,mousedown,click,dblclick在移动webkit上不支持,为系统放大功能),e.preventDefault时会阻止掉默认click事件的执行,必须要人为的在_end结束之后模拟click事件的调用,而其他正常手机即使调用了e.preventDefault也不会阻止click事件的触发,因为这些手机的默认浏览器上的元素的click事件的cancelable属性不为true,不可以被preventDefault取消掉,会正常执行,而如果在_end中模拟了click事件则将会导致click的重复调用(在有toggle状态的事件上非常明显),因此折中的方式参见下面的解决方案。

四、解决方案

1. 去除onBeforeScrollStart里的阻止默认行为

onBeforeScrollStart: function (e) { //e.preventDefault(); }

2. onBeforeScrollMove设置为

function (e) {e.preventDefault();}

以保证手机上的正常滑动免受浏览器默认行为影响(如下滑时会有窗口的scroll事件),当然如果这里不添加的话也可以在document的END_EV中阻止浏览器默认行为

3. _end 中将模拟事件名更改为END_EV或者直接去掉模拟事件的功能

iscroll.js是Matteo Spinelli开发的一个js文件,使用原生js编写,不依赖与任何js框架。旨在解决移动webkit系浏览器的区域滚动问题,兼容mobile safari、android默认浏览器、safari、chrome、firefox5+、opera11+、IE9+及其他webkit核心浏览器。最新版本为iscroll4。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值