為jQuery添加Webkit的觸摸的方法分享
這段代碼是我在做13年一份兼職的時(shí)候無(wú)聊加上去的,為jQuery添加觸摸事件的支持。因?yàn)樽龅糜悬c(diǎn)無(wú)聊,所以就幫客戶(hù)添加了用響應(yīng)式網(wǎng)頁(yè)+JS touch兼容了移動(dòng)設(shè)備,主要是Webkit的移動(dòng)設(shè)備。
這里就分享下我的實(shí)現(xiàn)。
先貼上代碼:
//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);
網(wǎng)上能找到很多關(guān)于Touch事件的相關(guān)信息,所以我就不詳細(xì)說(shuō)明了,可以解釋得簡(jiǎn)單一點(diǎn)。
觸摸事件代替鼠標(biāo)事件
在Webkit移動(dòng)設(shè)備上,觸摸操控首先會(huì)觸發(fā)觸摸事件,在0.5秒后才會(huì)觸摸鼠標(biāo)事件。
個(gè)人覺(jué)得這在設(shè)計(jì)上可以理解。先滿足于觸摸操控的需求,然后再向“下”兼容鼠標(biāo)事件,以滿足原有面向桌面網(wǎng)頁(yè)的使用。
所有的事件大致執(zhí)行順序是:touchstart->touchmove->touchend->0.5s->鼠標(biāo)事件mouseover/scroll/click等
按照webkit移動(dòng)瀏覽器的設(shè)計(jì),一般開(kāi)發(fā)時(shí)候按照桌面網(wǎng)頁(yè)開(kāi)發(fā),然后移動(dòng)設(shè)備上使用是沒(méi)問(wèn)題的。不過(guò)桌面上大量使用的hover類(lèi)效果時(shí)常會(huì)因?yàn)橛|摸把mouse事件+click事件觸發(fā)個(gè)遍而悲??;0.5秒的延遲也對(duì)用戶(hù)體驗(yàn)造成了大傷害。
所以我添加了tapOrClick事件,用途就是替代click事件,并且滅了那0.5秒。
滾動(dòng)鎖定
在用戶(hù)使用觸摸設(shè)備進(jìn)行滾動(dòng),而觸摸已經(jīng)停止的時(shí)候,瀏覽器會(huì)鎖定整個(gè)頁(yè)面,暫停所有UI資源占用,而把大部分資源留給內(nèi)核進(jìn)行滾動(dòng)。同樣的情況還會(huì)發(fā)生在放大縮小頁(yè)面內(nèi)容,甚至更甚。
因?yàn)橐觽€(gè)滾動(dòng)漸變的特效,所以我添加了moveOrScroll事件,在滑動(dòng)的時(shí)候執(zhí)行滾動(dòng)中應(yīng)該執(zhí)行的效果。
當(dāng)然,這里還是不完美的,因?yàn)槭种敢坏╇x開(kāi)屏幕(觸摸事件停止),頁(yè)面自由滾動(dòng)的這段時(shí)間,js也會(huì)被freeze。這只是沒(méi)有辦法中的辦法而已。
滾動(dòng)鎖定還會(huì)導(dǎo)致另一個(gè)問(wèn)題就是:滾動(dòng)有三種,分別是上下、左右、自由。
用一下觸摸設(shè)備就會(huì)發(fā)現(xiàn),如果從觸摸開(kāi)始被判定是上下滾動(dòng),那么觸摸時(shí)再怎么左右滑動(dòng)都不會(huì)有左右滑動(dòng)的效果,除非放開(kāi)重來(lái)。同樣的情況也會(huì)發(fā)生在一開(kāi)始為左右滾動(dòng)。自由滾動(dòng)的話需要一開(kāi)始就進(jìn)行斜向滾動(dòng)。
在這個(gè)時(shí)候如果需要加入特定事件的話,需要注意事件的判斷。在jQuery的事件回調(diào)參數(shù)中,假設(shè)參數(shù)名為e,那么一般用:
e.originalEvent.touches[0].pageX可以判斷觸摸情況。開(kāi)發(fā)時(shí)需要自行記錄觸摸事件的情況再作判斷。
原生最優(yōu)
請(qǐng)盡量不要嘗試用大量的JS方法觸發(fā)來(lái)實(shí)現(xiàn)一些本身沒(méi)有的樣式效果。
比如元素靜態(tài)不動(dòng),理應(yīng)用position:fix;來(lái)實(shí)現(xiàn),但許多開(kāi)發(fā)人員會(huì)是用js不斷刷新其控件位置來(lái)解決。
這種實(shí)現(xiàn)方式放在觸摸設(shè)備上,一般只會(huì)出現(xiàn)兩種情況:
1.卡死你
2.頁(yè)面被凍結(jié),凍結(jié)技術(shù)后突然發(fā)現(xiàn)事件全部執(zhí)行完了(原因如上,瀏覽器會(huì)集中UI線程的資源給內(nèi)核優(yōu)先)
一般移動(dòng)設(shè)備的屏幕有效刷新率不過(guò)30Hz,精簡(jiǎn)指令集的CPU本身也會(huì)慢一些,加上大部分的移動(dòng)設(shè)備都是...Android...
所以,性能必須盡量依賴(lài)原生提供的方法。一些Hack和Cover的方法對(duì)方受不了。
如何使用
當(dāng)時(shí)因?yàn)榧媛毥桓逗孟窬鸵粌芍艿氖虑?,所以沒(méi)有把代碼寫(xiě)得太好,不過(guò)還是能用。大致的用法跟普通的jQuery事件一致,命名和實(shí)現(xiàn)方面確實(shí)還值得商榷:
$('.sign .usernametip').tapOrClick(function () {
$(this).css('visibility', 'hidden');
$('.sign .username').focus();
});
跟項(xiàng)目中的很多事情一樣,許多事情看似簡(jiǎn)單,但實(shí)際上卻會(huì)出現(xiàn)各種各樣的問(wèn)題。
觸摸事件并不是簡(jiǎn)單地便可兼容,單實(shí)現(xiàn)了功能外還需要顧慮最實(shí)質(zhì)的問(wèn)題——特定的交互模式。
比如觸摸中需要隱藏許多空間以留有更多的空間給有限的用戶(hù)屏幕;許多本身以點(diǎn)擊切換的元素在觸摸的最佳體驗(yàn)中應(yīng)該改成滑動(dòng)切換,甚至要顧慮不同的滑動(dòng)情況;觸摸各事件的停留事件不同可能代表不同的操作,需要進(jìn)行判別......
雖然知道jQuery Mobile等已經(jīng)有比較完善的各種方法,不過(guò)就是忍不住自己實(shí)現(xiàn)一下看看。
相關(guān)文章
jQuery基于ajax實(shí)現(xiàn)帶動(dòng)畫(huà)效果無(wú)刷新柱狀圖投票代碼
這篇文章主要介紹了jQuery基于ajax實(shí)現(xiàn)帶動(dòng)畫(huà)效果無(wú)刷新柱狀圖投票代碼,通過(guò)使用jquery動(dòng)態(tài)操作頁(yè)面元素樣式屬性實(shí)現(xiàn)柱狀圖投票效果,非常具有實(shí)用價(jià)值,需要的朋友可以參考下2015-08-08
jquery選擇器和屬性對(duì)象的操作實(shí)例分析
這篇文章主要介紹了jquery選擇器和屬性對(duì)象的操作,結(jié)合實(shí)例形式分析了jquery選擇器與頁(yè)面元素屬性相關(guān)操作技巧,需要的朋友可以參考下2020-01-01
一步一步制作jquery插件Tabs實(shí)現(xiàn)過(guò)程
自制一個(gè)簡(jiǎn)潔的tabs插件還是有必要的在設(shè)計(jì)之前,先整理好思路,實(shí)現(xiàn)tabs,自動(dòng)輪換,ajax等主要功能,然后是dom的排列形式,這里采用傳統(tǒng)的2010-07-07
jQuery實(shí)現(xiàn)圖片信息的浮動(dòng)顯示實(shí)例代碼
圖片信息的浮動(dòng)顯示的效果,在網(wǎng)頁(yè)應(yīng)用中還是比較流行的,下面為大家詳細(xì)介紹下使用jquery是如何實(shí)現(xiàn)的,喜歡的朋友可以參考下2013-08-08
淺談jquery回調(diào)函數(shù)callback的使用
這篇文章主要簡(jiǎn)單介紹了jquery回調(diào)函數(shù)callback的使用,需要的朋友可以參考下2015-01-01
用jquery寫(xiě)的一個(gè)萬(wàn)年歷(自寫(xiě))
萬(wàn)年歷,想必大家對(duì)它都不陌生吧,下面是使用jquery寫(xiě)的一個(gè)萬(wàn)年歷示例,喜歡的朋友可以參考下2014-01-01
jQuery mobile在頁(yè)面加載時(shí)添加加載中效果 document.ready 和window.onload執(zhí)行順序
這篇文章主要介紹了jQuery mobile在頁(yè)面加載時(shí)添加加載中效果 document.ready 和window.onload執(zhí)行順序比較,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下2016-07-07

