這段代碼是我在做13年一份兼職的時候無聊加上去的,為jQuery添加觸摸事件的支援。因為做得有點無聊,所以就幫客戶添加了用響應式網頁+JS touch相容了行動裝置,主要是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); 網上能找到很多關於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等已經有比較完善的各種方法,不過就是忍不住自己實現一下看看。