iScroll5 安卓手机点击事件失效

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。


替换代码:

onBeforeScrollStart:function(e) {

varnodeType = e.explicitOriginalTarget? e.explicitOriginalTarget.nodeName.toLowerCase():(e.target?e.target.nodeName.toLowerCase():'');if(nodeType !='select'&& nodeType !='option'&& nodeType !='input'&& nodeType!='textarea') e.preventDefault();

//e.preventDefault();

},

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 总结: 鼠标事件 1.click与dbclick事件$ele.click()$ele.click(handler(...
    阿r阿r阅读 5,531评论 2 10
  • @转自GitHub 介绍js的基本数据类型。Undefined、Null、Boolean、Number、Strin...
    YT_Zou阅读 4,937评论 0 0
  • 第1章 鼠标事件 1-1 jQuery鼠标事件之click与dbclick事件 用交互操作中,最简单直接的操作就是...
    mo默22阅读 5,048评论 0 6
  • H5 meta详解 viewport width:控制 viewport 的大小,可以指定的一个值,如果 600,...
    FConfidence阅读 4,243评论 0 3
  • 文/千古为序 昨天开毕业年级会议的时候,校长谈到了“上学无用论。”他是这样说的:“如果上清华北大的学生中,有一个生...
    千古作序阅读 3,280评论 0 0