前些日子收到邮件,之前兼职的一个项目被转给了其他人,跟进的人来问我相关代码的版权问题。

我就呵呵了。

这段代码是我在做13年一份兼职的时候无聊加上去的,为jQuery添加触摸事件的支持。因为做得有点无聊,所以就帮客户添加了用响应式网页+JS touch兼容了移动设备,主要是Webkit的移动设备。

这里就分享下我的实现。

先贴上代码:

//Published by Indream Luo
//Contact: indreamluo@qq.com
//Version: Chinese 1.0.0 !function ($) {
window.indream = window.indream || {};
$.indream = indream; //Define events
indream.touch = {
evenList: {
touchStart: {
htmlEvent: 'touchstart'
},
touchMove: {
htmlEvent: 'touchmove'
},
touchEnd: {
htmlEvent: 'touchend'
},
tapOrClick: {
eventFunction: function (action) {
$(this).each(function () {
(function (hasTouched) {
$(this).touchEnd(function (e) {
hasTouched = true;
action.call(this, e);
});
$(this).click(function (e) {
if (!hasTouched) {
action.call(this, e);
}
});
}).call(this, false);
}); return this;
}
},
moveOrScroll: {
eventFunction: function (action) {
$(this).each(function () {
(function (hasTouched) {
$(this).touchMove(function (e) {
hasTouched = true;
action.call(this, e);
});
$(this).scroll(function (e) {
if (!hasTouched) {
action.call(this, e);
}
});
}).call(this, false);
}); return this;
}
}
}
} //Add events into jquery
for (var eventName in indream.touch.evenList) {
var event = indream.touch.evenList[eventName];
$.fn[eventName] = event.eventFunction || (function (eventName, htmlEvent) {
return function (action) {
$(this).each(function () {
$(this).bind(htmlEvent, action);
//Add event listener method for IE or others
if (this.attachEvent) {
this.attachEvent('on' + htmlEvent, function (e) {
$(this).on(eventName);
});
} else {
this.addEventListener(htmlEvent, function (e) {
$(this).on(eventName);
});
}
}); return this;
}
})(eventName, event.htmlEvent);
}
}(window.jQuery);

网上能找到很多关于Touch事件的相关信息,所以我就不详细说明了,可以解释得简单一点。

触摸事件代替鼠标事件

在Webkit移动设备上,触摸操控首先会触发触摸事件,在0.5秒后才会触摸鼠标事件。

个人觉得这在设计上可以理解。先满足于触摸操控的需求,然后再向“下”兼容鼠标事件,以满足原有面向桌面网页的使用。

所有的事件大致执行顺序是:touchstart->touchmove->touchend->0.5s->鼠标事件mouseover/scroll/click等

按照webkit移动浏览器的设计,一般开发时候按照桌面网页开发,然后移动设备上使用是没问题的。不过桌面上大量使用的hover类效果时常会因为触摸把mouse事件+click事件触发个遍而悲剧;0.5秒的延迟也对用户体验造成了大伤害。

所以我添加了tapOrClick事件,用途就是替代click事件,并且灭了那0.5秒。

滚动锁定

在用户使用触摸设备进行滚动,而触摸已经停止的时候,浏览器会锁定整个页面,暂停所有UI资源占用,而把大部分资源留给内核进行滚动。同样的情况还会发生在放大缩小页面内容,甚至更甚。

因为要加个滚动渐变的特效,所以我添加了moveOrScroll事件,在滑动的时候执行滚动中应该执行的效果。

当然,这里还是不完美的,因为手指一旦离开屏幕(触摸事件停止),页面自由滚动的这段时间,js也会被freeze。这只是没有办法中的办法而已。

滚动锁定还会导致另一个问题就是:滚动有三种,分别是上下、左右、自由。

用一下触摸设备就会发现,如果从触摸开始被判定是上下滚动,那么触摸时再怎么左右滑动都不会有左右滑动的效果,除非放开重来。同样的情况也会发生在一开始为左右滚动。自由滚动的话需要一开始就进行斜向滚动。

在这个时候如果需要加入特定事件的话,需要注意事件的判断。在jQuery的事件回调参数中,假设参数名为e,那么一般用:

e.originalEvent.touches[0].pageX

可以判断触摸情况。开发时需要自行记录触摸事件的情况再作判断。

原生最优

请尽量不要尝试用大量的JS方法触发来实现一些本身没有的样式效果。

比如元素静态不动,理应用position:fix;来实现,但许多开发人员会是用js不断刷新其控件位置来解决。

这种实现方式放在触摸设备上,一般只会出现两种情况:

  1. 卡死你
  2. 页面被冻结,冻结技术后突然发现事件全部执行完了(原因如上,浏览器会集中UI线程的资源给内核优先)

一般移动设备的屏幕有效刷新率不过30Hz,精简指令集的CPU本身也会慢一些,加上大部分的移动设备都是...Android...

所以,性能必须尽量依赖原生提供的方法。一些Hack和Cover的方法对方受不了。

如何使用

当时因为兼职交付好像就一两周的事情,所以没有把代码写得太好,不过还是能用。大致的用法跟普通的jQuery事件一致,命名和实现方面确实还值得商榷:

$('.sign .usernametip').tapOrClick(function () {
$(this).css('visibility', 'hidden');
$('.sign .username').focus();
});

更多

跟项目中的很多事情一样,许多事情看似简单,但实际上却会出现各种各样的问题。

触摸事件并不是简单地便可兼容,单实现了功能外还需要顾虑最实质的问题——特定的交互模式。

比如触摸中需要隐藏许多空间以留有更多的空间给有限的用户屏幕;许多本身以点击切换的元素在触摸的最佳体验中应该改成滑动切换,甚至要顾虑不同的滑动情况;触摸各事件的停留事件不同可能代表不同的操作,需要进行判别......

虽然知道jQuery Mobile等已经有比较完善的各种方法,不过就是忍不住自己实现一下看看。

为jQuery添加Webkit的触摸方法支持的更多相关文章

  1. 给Jquery添加alert,prompt方法,类似系统的Alert,Prompt,可以响应键盘,支持拖动

    我们在调用系统的Alert,prompt的弹出提示时,不同的系统会有不同的提示框,视觉效果不统一,而且不好看,功能单一,现在我们通过Jquery模拟Alert,prompt,现实统一视觉效果,而且内容 ...

  2. JS添加节点方法与JQuery添加节点方法的比较及总结

    原生JS添加节点方法与JQuery添加节点方法的比较及总结   一.首先构建一个简单布局,来供下边讲解使用 1.HTML部分代码: <div id="div1">div ...

  3. JQuery为元素添加样式的实现方法

    由于jquery支持css3,所有能很好的兼容很多浏览器,所以通过jquery来使用css样式比较好 为定义好的css样式可以调用元素的css方法添加样式 $("span").cs ...

  4. 如何为jquery添加方法

    以下内容引自一位网友的帖子: jQuery插件的开发包括两种: 一种是类级别的插件开发,即给jQuery添加新的全局函数,相当于给jQuery类本身添加方法.jQuery的全局函数就是属于jQuery ...

  5. 为Promise添加finally方法支持,把小程序函数变成promise函数

    // 为Promise添加finally方法支持 Promise.prototype.finally = function (callback) {   let P = this.constructo ...

  6. jquery添加html代码的几种方法

    经常用jq来DOM添加html代码 就总结了jq里面最常用的动态添加html代码的方法 append在元素内部的尾部加上元素 prepend在元素内部的前部加上元素 after在元素外部的尾部加上元素 ...

  7. jQuery中的事件绑定方法

    在jQuery中,事件绑定方法大致有四种:bind(),live(), delegate(),和on(). 那么在工作中应该如何选择呢?首先要了解四种方法的区别和各自的特点. 在了解这些之前,首先要知 ...

  8. jQuery 跨域访问问题解决方法(转)

    转自:http://www.jb51.net/article/21213.htm 浏览器端跨域访问一直是个问题, 多数研发人员对待js的态度都是好了伤疤忘了疼,所以病发的时候,时不时地都要疼上一疼.记 ...

  9. 深入理解jQuery中live与bind方法的区别

    本篇文章主要是对jQuery中live与bind方法的区别进行了详细的分析介绍,需要的朋友可以过来参考下,希望对大家有所帮助 注意如果是通过jq添加的层和对象一定要用live(),用其他的都不起作用 ...

随机推荐

  1. C# 图片无损压缩

    /// <summary> /// 图像缩略图处理 /// </summary> /// <param name="bytes">图像源数据&l ...

  2. oracle函数简析

    (一).数值型函数(Number Functions) 数值型函数输入数字型参数并返回数值型的值.多数该类函数的返回值支持38位小数点,诸如:COS, COSH, EXP, LN, LOG, SIN, ...

  3. Unity.Interception(AOP)

            在前面我们学习到的是Unity依赖注入(DI)与统一容器来松散耦合,这个设计已经对我们系统带来了很多的好处.但是我们还会想尝试和遵循单一职责,开放封闭原则.比如我们不应该在我们的Bus ...

  4. JAVA安装过程中出现的“javac不是内部或外部指令”的解决方法

    近来重新安装了JAVA,安装过程中出现问题,网上找到解决办法,汇总发布. 解决流程: 1.确定自己的环境变量设置没问题,没有出现遗漏 : . 等情况 (具体环境变量设置百度) 2.环境变量设置后 ,d ...

  5. [译]App Framework 2.1 (1)之 Quickstart

    最近有移动App项目,选择了 Hybrid 的框架Cordova  和  App Framework 框架开发. 本来应该从配置循序渐进开始写的,但由于上班时间太忙,这段时间抽不出空来,只能根据心情和 ...

  6. myeclipse中source not found问题解决办法

    myeclipse中出现source not found是因为你所引用的JavaEE Generic Library没有关联源码,如下图: 下面给出该问题的解决办法: 步骤一:去下载apache-to ...

  7. Matlab读取数据中出现的问题

    在运行Matlab读取一段数据并做处理的时候,常常会提示服务器错误,但是等待一会再次运行就会成功运行. 代码如下: clc; clear all; [~,~,rawdata] = xlsread('进 ...

  8. C#_取随机字符

    1.多位数字字母组成,每位取值0-9A-Z /// <summary> /// 获取下一个顺序码根据上一个(数字字母组合) /// </summary> /// <par ...

  9. overflow:hidden清除浮动原理

    overflow:hidden的意思是超出部分去掉,如果父元素height为auto,内部元素浮动,势必会将内部元素全部隐藏,故计算出内部浮动高度顺便清除浮动.

  10. python 虚拟环境

    python3 目录venv创建为虚拟环境,并激活. $ python3 -m venv ./venv$ source venv/bin/activate -m: -m mod : run libra ...