zoukankan      html  css  js  c++  java
  • 为jQuery添加Webkit的触摸方法支持

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

    我就呵呵了。

    这段代码是我在做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);
    View Code

    网上能找到很多关于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等已经有比较完善的各种方法,不过就是忍不住自己实现一下看看。

  • 相关阅读:
    博客转移到cnblogs
    mmsplayer for ios 支持iphone ,ipad,ipod touch 版本已经完成。
    mmsplayer for ios v1.0
    无ldf文件情况下恢复数据库数据纪实
    我的Blog页面设计
    使用C#生成静态页面
    C++开发工具
    使用JNDI来读取Notes通讯录中的数据
    关于Char与string
    JavaScript站点荟萃
  • 原文地址:https://www.cnblogs.com/indream/p/3537128.html
Copyright © 2011-2022 走看看