fastclick 解决js穿透问题
http://www.tuicool.com/articles/VniQRr
http://www.cnblogs.com/MrBackKom/archive/2012/06/26/2564501.html
之前翻译过一篇关于fastclick的快速点击文章http://www.cnblogs.com/lilyimage/p/3568773.html ,fastclick可以解决在手机上点击事件的300ms延迟;另外我们也知道zepto的touch模块,帮助我们实现了很多手机上的事件,比如tap等,tap事件也是为了解决在click的延迟问题。那么他们有什么区别呢?
先看zepto的touch模块实现:
1 $(document)
2 .on('touchstart ...',function(e){
3 ...
4 ...
5 now = Date.now()
6 delta = now - (touch.last || now)
7 if (delta > 0 && delta <= 250) touch.isDoubleTap = true
8 touch.last = now
9 })
10 .on('touchmove ...', function(e){
11 })
12 .on('touchend ...', function(e){
13 ...
14 if (deltaX < 30 && deltaY < 30) {
15 var event = $.Event('tap')
16
17 touch.el.trigger(event)
18 }
19 })
touch模块绑定事件touchstart,touchmove和touchend到document上,然后通过计算touch事件触发的时间差,位置差来实现了自定义的tap,swipe等。
那么tap事件为什么会“穿透”呢?
比如下面的代码:
<html>
<head>
<meta charset="UTF-8">
<script type="text/javascript" src="/resources/js/zepto.js"></script>
<script type="text/javascript" src="/resources/js/zepto-touch.js"></script>
<title></title>
</head>
<body>
<style>
.q{width: 200px;height: 200px;background-color: red;position: absolute;top:0;;left: 0}
.b{width: 300px;height: 300px;background-color: green;position: absolute;top:0;;left: 0}
</style> <div class="b"></div>
<div class="q"></div>
<script>
$('.q').on('tap',function(e){
$(this).hide();
});
$('.b').on('click',function(e){
alert("bb");
});
</script>
</body>
</html>
在手机上,点击了q以后,就会弹出bb的弹框,为什么呢?
因为tap事件是通过document绑定了touchstart和touchend事件实现,$('.q')上,当touchend事件冒泡到document上以后执行$(this).hide();此时$('.b'),就处在了页面的最前面,
现在touchend冒泡到了document上,并且$('.b')在页面的最前面,然后就触发了click事件。
关于click事件300ms延迟的由来,以及随着时间的发展,遇到的问题,各家浏览器的解决方法和现在的各种js的方法,可以见http://blogs.telerik.com/appbuilder/posts/13-11-21/what-exactly-is.....-the-300ms-click-delay 准备翻译下。因为里面也介绍了fastclick,呵呵。
所以zepto的touch模块真的不是一个好的模块。。不过比我自己写的好,关键是为什么一直都不解决这个点透的问题啊。。
fastclick呢?
它的实际原理是在 目标元素 上绑定touchstart ,touchend事件,然后在touchend结束的时候立马执行click事件,这样就解决了“点透”的问题(实质是事件冒泡导致)以及300ms延迟问题,300ms延迟是因为浏览器为了实现用户双击屏幕放大页面(double tap to zoom 详细见我下一篇翻译吧)的效果。
FastClick.prototype.sendClick = function(targetElement, event) {
'use strict';
var clickEvent, touch;
// On some Android devices activeElement needs to be blurred otherwise the synthetic click will have no effect (#24)
if (document.activeElement && document.activeElement !== targetElement) {
document.activeElement.blur();
}
touch = event.changedTouches[0];
// 这里就是关键,就是在这里实现了click事件
clickEvent = document.createEvent('MouseEvents');
clickEvent.initMouseEvent(this.determineEventType(targetElement), true, true, window, 1, touch.screenX, touch.screenY, touch.clientX, touch.clientY, false, false, false, false, 0, null);
clickEvent.forwardedTouchEvent = true;
targetElement.dispatchEvent(clickEvent);
};
在touchEnd的时候会立马调用这个sendClick
FastClick.prototype.onTouchEnd = function(event){
......
this.sendClick(targetElement, event);
}
好了,这两个就是这样了。
fastclick 解决js穿透问题的更多相关文章
- 用Fastclick解决移动端300ms延迟问题
移动设备上的浏览器默认会在用户点击屏幕大约延迟300毫秒后才会触发点击事件,这是为了检查用户是否在做双击. 为了能够立即响应用户的点击事件,才有了FastClick. 用法: 引入fastclick. ...
- 爬虫:selenium + phantomjs 解决js抓取问题(一)
selenium模块主要用来做测试,模拟键盘.鼠标来操作浏览器. phantomjs 就像一个无界面的浏览器一样. 两个结合能很好的解决js抓取的问题. 测试代码: #coding=utf-8 fro ...
- bower解决js的依赖管理
bower解决js的依赖管理 前言: 一个新的web项目开始,我们总是很自然地去下载需要用到的js类库文件,比如jQuery,去官网下载名为jquery-1.10.2.min.js文件,放到我们的项目 ...
- 解决js跨域问题
如何解决js跨域问题 Js跨域问题是web开发人员最常碰到的一个问题之一.所谓js跨域问题,是指在一个域下的页面中通过js访问另一个不同域下 的数据对象,出于安全性考 虑,几乎所有浏览器都不允许这种跨 ...
- promise 的基本概念 和如何解决js中的异步编程问题 对 promis 的 then all ctch 的分析 和 await async 的理解
* promise承诺 * 解决js中异步编程的问题 * * 异步-同步 * 阻塞-无阻塞 * * 同步和异步的区别? 异步;同步 指的是被请求者 解析:被请求者(该事情的处理者)在处理完事情的时候的 ...
- 使用call、apply和bind解决js中烦人的this,事件绑定时的this和传参问题
1.什么是this 在JavaScript中this可以是全局对象.当前对象或者任意对象,这完全取决于函数的调用方式,this 绑定的对象即函数执行的上下文环境(context). 为了帮助理解,让我 ...
- pyspider示例代码一:利用phantomjs解决js问题
本系列文章主要记录和讲解pyspider的示例代码,希望能抛砖引玉.pyspider示例代码官方网站是http://demo.pyspider.org/.上面的示例代码太多,无从下手.因此本人找出一下 ...
- 如何解决js跨域问题
Js跨域问题是web开发人员最常碰到的一个问题之一.所谓js跨域问题,是指在一个域下的页面中通过js访问另一个不同域下的数据对象,出于安全性考 虑,几乎所有浏览器都不允许这种跨域访问,这就导致在一些a ...
- Java模拟并解决缓存穿透
什么叫做缓存穿透 缓存穿透只会发生在高并发的时候,就是当有10000个并发进行查询数据的时候,我们一般都会先去redis里面查询进行数据,但是如果redis里面没有这个数据的时候,那么这10000个并 ...
随机推荐
- javascript中无法通过div.style.left获取值的问题
一.问题总结: 样式必须直接写在元素内部才能通过div.style.left直接获取属性值(也就是必须是内联样式才行),定义在css中的样式不能通过这种方式获取. 让元素移动到200停止 setTim ...
- 《Javascript高级程序设计第3版》精华总结
一.JavaScript简介 1.1 javascript简史 1.2 javascript实现 + javascript是一种专为网页交互而设计的一种脚本语言,javascript由三大部分组成 ...
- 从click事件理解DOM事件流
事件流是用来解释页面上的不同元素接受一个事件的顺序,首先要明确两点: 1.一个事件的影响元素可能不止一个(同心圆理论),但目标元素只有一个. 2.如果这些元素都绑定了相同名称的事件函数,我们怎么知道这 ...
- Unity关于脚本前面的勾选框
今天做项目时需要在某个事件条件下禁用某个脚本,但是突然发现这个脚本前面没有勾选框,,,就像这样 网上搜了下,原来是需要在脚本中加上void Start()方法,即使这个方法里什么都没有 void St ...
- java安全沙箱(一)之ClassLoader双亲委派机制
java是一种类型安全的语言,它有四类称为安全沙箱机制的安全机制来保证语言的安全性,这四类安全沙箱分别是: 类加载体系 .class文件检验器 内置于Java虚拟机(及语言)的安全特性 安全管理器及J ...
- 如何使用Math对象快速计算数组中的最大值或最小值
Math 对象下包含 min() 和 max() 方法 用于确定一组数值中的最大值和最小值.这两个方法都可以接收任意多个数值参数. var max = Math.max(1,2,3,4,5,6); c ...
- makefile 函数集
1 if 函数 语法 $(if CONDITION,THEN-PART[,ELSE-PART]) 功能 第一个参数"CONDITION",在函数执行时忽略其前导和结尾空字符,如果包 ...
- MYSQL PERFORMANCE_SCHEMA HINTS
ACCOUNTS NOT PROPERLY CLOSING CONNECTIONS [ 1 ] Works since 5.6 SELECT ess.user, ess.host , (a.total ...
- 修饰符const,static与readonly
在c语言中,存储区可以分成代码区,全局区(用于存放全局变量和静态变量),常量区(用户存放常量),栈,堆. 首先介绍const,const是常量的标志,表示变量不可被修改.const变量,申明的时候就必 ...
- MyBatis的应用
a)首先先导入固定的jar包 b)添加mybatis配置文件mybatis-config.xml 1.添加mybatis配置文件mybatis-config.xml <?xml version= ...