基于jQuery的前端如何做到无伤迁移
2015-08-17 16:14
816 查看
首先,解释一下我个人对前端无伤迁移的理解,即移动端和PC端使用同一套代码,或者说原本在PC端运行得很完美的代码,只要修改少许,就可以在移动端完美运行。
当然,大部分的公司会专门为移动端设计了一套,同时,有为PC端设计了一套,这是最完美的结果。但某些情况下,PC和移动端同时用一套时,就要想办法解决了。
最近刚做完一个项目,项目组要求前端同时支持PC端和平板电脑,UI不太复杂,所以布局问题不大,但交互就有点麻烦了。
众所周知,移动端的click事件有300ms的延迟,所以首要的问题要解决这个。由于之前阅读过Zepto的源码,所以第一时间把要模拟tap事件的想法去掉了,这个实在是太可怕了,我除了要绑定click事件外,我还要另外绑定个tap事件,除此之外,我还要另外绑定个touchstart||touchmove||touchend事件,把click事件禁用掉,或者是判断是否为移动设备,再根据这个来绑定tap或click事件,修改的成本实在太大了。想到某个前端技术群里面有人推荐了fastclick,打开源码看了一下,狂喜。我根本无须修改任何代码,只需要引入然后再添加FastCLick.attach就行了,至此,click事件在移动端300ms的延迟完美解决。
注:其实fastclick的实现原理跟zepto的tap模拟差不多,都是基于touchstart,touchmove还有touchend实现的,但fastclick最终会手动出发click事件,即dispathEvent,而zepto则是触发tap事件,同时fastclick会在touchstart时调用e.preventDefault(),以防止click事件的二次触发。
紧接着,就要面临第二个问题了。在PC端,有鼠标事件,例如,mousedown,mousemove,mouseup,相对应地,移动端有touchstart,touchmove和touchend事件,如何将这两个映射起来呢?如何做到在PC端就绑定mouse事件,在移动端就绑定touch事件呢?由于这个页面是基于jQuery搭建起来的,所以,必须研究一下jQuery的实现。果不其然,我在jQuery.event.add看到了如下代码:
![](http://images0.cnblogs.com/blog2015/653666/201508/171547498318037.png)
即使不看源码,从注释中我们也可以得知,当special[type]存在时,如果selector存在,即取special.delegateType,否则取special.bindType;若special[type]不存在,取原type,根据这个,我们可以做一些映射了。
这样的话,当代码是如下时:
其在PC端,绑定的是mousedown事件,在移动端,绑定的是toushstart事件了。
最后,还有一个非常关键的问题,就是坐标的获取。当你在PC端的时候,你可以使用e.pageX来获取,但移动端,你却要使用e.originalEvent.changedTouches[0].pageX来获取,这个必须得解决。
![](http://images0.cnblogs.com/blog2015/653666/201508/171604407223770.png)
从上面的代码可以得知,事件在jQuery.event.dispath中触发,而在这个方法中
![](http://images0.cnblogs.com/blog2015/653666/201508/171606528166015.png)
jQuery对调用jQuery.event.fix()来对原生的event做一些兼容性的修改,那么我们可以在jQuery.event.dispath做一些文章。
至此,你无须再修改其他代码,只需要添加这些补丁,就可以做到无伤迁移了。
当然,大部分的公司会专门为移动端设计了一套,同时,有为PC端设计了一套,这是最完美的结果。但某些情况下,PC和移动端同时用一套时,就要想办法解决了。
最近刚做完一个项目,项目组要求前端同时支持PC端和平板电脑,UI不太复杂,所以布局问题不大,但交互就有点麻烦了。
众所周知,移动端的click事件有300ms的延迟,所以首要的问题要解决这个。由于之前阅读过Zepto的源码,所以第一时间把要模拟tap事件的想法去掉了,这个实在是太可怕了,我除了要绑定click事件外,我还要另外绑定个tap事件,除此之外,我还要另外绑定个touchstart||touchmove||touchend事件,把click事件禁用掉,或者是判断是否为移动设备,再根据这个来绑定tap或click事件,修改的成本实在太大了。想到某个前端技术群里面有人推荐了fastclick,打开源码看了一下,狂喜。我根本无须修改任何代码,只需要引入然后再添加FastCLick.attach就行了,至此,click事件在移动端300ms的延迟完美解决。
注:其实fastclick的实现原理跟zepto的tap模拟差不多,都是基于touchstart,touchmove还有touchend实现的,但fastclick最终会手动出发click事件,即dispathEvent,而zepto则是触发tap事件,同时fastclick会在touchstart时调用e.preventDefault(),以防止click事件的二次触发。
紧接着,就要面临第二个问题了。在PC端,有鼠标事件,例如,mousedown,mousemove,mouseup,相对应地,移动端有touchstart,touchmove和touchend事件,如何将这两个映射起来呢?如何做到在PC端就绑定mouse事件,在移动端就绑定touch事件呢?由于这个页面是基于jQuery搭建起来的,所以,必须研究一下jQuery的实现。果不其然,我在jQuery.event.add看到了如下代码:
![](http://images0.cnblogs.com/blog2015/653666/201508/171547498318037.png)
即使不看源码,从注释中我们也可以得知,当special[type]存在时,如果selector存在,即取special.delegateType,否则取special.bindType;若special[type]不存在,取原type,根据这个,我们可以做一些映射了。
var ua = navigator.userAgent; var isMobileDevice = /Windows Phone|Android|iP(?:ad|hone|od)|BB10/.test(ua); if (isMobileDevice) { special = jQuery.event.special; special.mousedown = {'delegateType': 'touchstart', 'bindType': 'touchstart'}; special.mouseup = {'delegateType': 'touchend', 'bindType': 'touchend'}; special.mousemove = {'delegateType': 'touchmove', 'bindType': 'touchmove'}; }
这样的话,当代码是如下时:
$(document).on('mousedown', function() { console.log('a'); });
其在PC端,绑定的是mousedown事件,在移动端,绑定的是toushstart事件了。
最后,还有一个非常关键的问题,就是坐标的获取。当你在PC端的时候,你可以使用e.pageX来获取,但移动端,你却要使用e.originalEvent.changedTouches[0].pageX来获取,这个必须得解决。
![](http://images0.cnblogs.com/blog2015/653666/201508/171604407223770.png)
从上面的代码可以得知,事件在jQuery.event.dispath中触发,而在这个方法中
![](http://images0.cnblogs.com/blog2015/653666/201508/171606528166015.png)
jQuery对调用jQuery.event.fix()来对原生的event做一些兼容性的修改,那么我们可以在jQuery.event.dispath做一些文章。
var ua = navigator.userAgent, isMobileDevice, oldDispath, special; oldDispath = jQuery.event.dispatch; isMobileDevice = /Windows Phone|Android|iP(?:ad|hone|od)|BB10/.test(ua); if (isMobileDevice) { special = jQuery.event.special; special.mousedown = {'delegateType': 'touchstart', 'bindType': 'touchstart'}; special.mouseup = {'delegateType': 'touchend', 'bindType': 'touchend'}; special.mousemove = {'delegateType': 'touchmove', 'bindType': 'touchmove'}; jQuery.event.dispatch = function(event) { var args = Array.prototype.slice.call(arguments, 1), touch; event = jQuery.event.fix(event); //修复touch事件 if (event.originalEvent && event.originalEvent.changedTouches) { touch = event.originalEvent.changedTouches[0]; event.pageX = touch.pageX; event.pageY = touch.pageY; } args.unshift(event); oldDispath.apply(this, args); } }
至此,你无须再修改其他代码,只需要添加这些补丁,就可以做到无伤迁移了。
相关文章推荐
- 基于jquery的响应式提示框SweetAlert
- jquery核心方法《探究》
- Jquery-DataTable 使用介绍
- 消除jquery Mobile自动添加的样式
- 定位锚平滑滚动jQuery代码
- 常见26个jquery使用技巧详解(比如禁止右键点击、隐藏文本框文字等)
- JQuery EasyUI DataGrid 获取属性值
- Js、Jquery字符串数字比较大小。
- JS,Jquery获取各种屏幕的宽度和高度
- jquery 插件开发基础知识
- jQuery Ajax 实例 全解析
- 【jQuery】 jQuery上下飘动效果
- JQuery放大镜效果
- 使用jQuery+css实现选项卡切换功能
- jquery动感漂浮导航菜单代码分享
- jQuery 控制表单和表格
- jQuery--样式的操作
- 【JQuery的选择器】
- jquery基础精华05
- jquery基础精华04(01)