在移动设备(如iPad、Galaxy Tab)上浏览网站时,当我点击一个元素(普通链接或使用javascript/jquery使可点击其他任何东西)时,总会出现延迟。
在网上阅读的过程中,我发现浏览器使用touchstart事件后跟随touchend事件,然后触发常规的click事件。是否有一种方式可以更快速地响应轻击并删除延迟的click事件?也许可以使用javascript或其他方法吗?
这是一个源自Matt的库(https://dev59.com/2FPTa4cB1Zd3GeqPnerc#9370637),并经过Google代码改编的jQuery插件。
使用方式如下:$('mySelector').fastClick(handler);
(function($){
var clickbuster = {
preventGhostClick: function(x, y) {
clickbuster.coordinates.push(x, y);
window.setTimeout(clickbuster.pop, 2500);
},
pop: function() {
clickbuster.coordinates.splice(0, 2);
},
onClick: function(event) {
for (var i = 0; i < clickbuster.coordinates.length; i += 2) {
var x = clickbuster.coordinates[i];
var y = clickbuster.coordinates[i + 1];
if (Math.abs(event.clientX - x) < 25 && Math.abs(event.clientY - y) < 25) {
event.stopPropagation();
event.preventDefault();
}
}
}
};
var methods = {
init: function(handler){
return this.each(function() {
var $this = $(this),
data = $this.data('fastClick');
if(!data){
this.addEventListener('touchstart', methods.handleEvent, false);
this.addEventListener('click', methods.handleEvent, false);
$this.data('fastClick', {
target: $this,
handler: handler
});
}
});
},
handleEvent:function(event) {
switch (event.type) {
case 'touchstart': $(this).fastClick('onTouchStart',event); break;
case 'touchmove': $(this).fastClick('onTouchMove',event); break;
case 'touchend': $(this).fastClick('onClick',event); break;
case 'click': $(this).fastClick('onClick',event); break;
}
},
onTouchStart: function(event) {
event.stopPropagation();
this[0].addEventListener('touchend', methods.handleEvent, false);
var _this = this;
document.body.addEventListener('touchmove', function(event){
methods.handleEvent.apply(_this,[event]);
}, false);
$(this).data('fastClick').startX = event.touches[0].clientX;
$(this).data('fastClick').startY = event.touches[0].clientY;
},
onTouchMove: function(event) {
if (Math.abs(event.touches[0].clientX - this.data('fastClick').startX) > 10 ||
Math.abs(event.touches[0].clientY - this.data('fastClick').startY) > 10) {
this.fastClick('reset');
}
},
onClick: function(event) {
event.stopPropagation();
$(this).fastClick('reset');
$(this).data('fastClick').handler.call(this,event);
if (event.type == 'touchend') {
clickbuster.preventGhostClick($(this).data('fastClick').startX, $(this).data('fastClick').startY);
}
},
reset: function() {
this[0].removeEventListener('touchend', methods.handleEvent, false);
document.body.removeEventListener('touchmove', methods.handleEvent, false);
}
}
$.fn.fastClick = function(method) {
if (methods[method]) {
return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
} else if ( typeof method === 'object' || typeof method === 'function' || !method) {
return methods.init.apply(this, arguments);
} else {
$.error('Method ' + method + ' does not exist on jQuery.hScroll');
}
}
clickbuster.coordinates = [];
document.addEventListener('click', clickbuster.onClick, true);
})(jQuery);
我使用检测来判断设备是否支持触摸,就像现代化一样。如果是触摸设备,我会将一个名为touchClick
的变量填充为选项'click'
或'touchend'
,根据结果而定。在jQuery中,我只需调用:
$('element').on(touchClick, function(e){ //do something });
它的占用空间非常小。
$('a').fastClick(function(){alert($(this).attr('href'))});
我该怎么做才能让它工作? - Rich Bradshawtouch
而不是click
吗?我很确定touch
没有延迟。 - Rich Bradshaw