如何从 iOS 上的移动 Safari 中消除点击/点击延迟?
我已经摆弄了很多事件侦听器,并且使用了一堆不同的脚本(例如Lightning Touch)而没有乐趣。有一些可行的解决方案,但是这些类型的脚本会强制您将目标元素编码到 DOM 上的每个链接。不幸的是,这可能会导致一些快速和一些缓慢的转换,这对我不起作用。
如何从 iOS 上的移动 Safari 中消除点击/点击延迟?
我已经摆弄了很多事件侦听器,并且使用了一堆不同的脚本(例如Lightning Touch)而没有乐趣。有一些可行的解决方案,但是这些类型的脚本会强制您将目标元素编码到 DOM 上的每个链接。不幸的是,这可能会导致一些快速和一些缓慢的转换,这对我不起作用。
经过不知疲倦的搜索,我终于找到了速度问题的答案,它以 FastClick 的形式出现(这个线程非常详细,以及其他用户评论中的一些调整)。
合并 FastClick.js 脚本,添加 onLoad 侦听器,并将您的<body>
内容包装在一个跨度中,您的应用程序应该开始感觉更加原生。
加载监听器: <body onLoad="initFastButtons();">
跨度包装:
<body onLoad="initFastButtons();">
<span id="fastclick">
[...]
</span>
</body>
快速点击.js
//======================================================== FASTCLICK
function FastButton(element, handler) {
this.element = element;
this.handler = handler;
element.addEventListener('touchstart', this, false);
};
FastButton.prototype.handleEvent = function(event) {
switch (event.type) {
case 'touchstart': this.onTouchStart(event); break;
case 'touchmove': this.onTouchMove(event); break;
case 'touchend': this.onClick(event); break;
case 'click': this.onClick(event); break;
}
};
FastButton.prototype.onTouchStart = function(event) {
event.stopPropagation();
this.element.addEventListener('touchend', this, false);
document.body.addEventListener('touchmove', this, false);
this.startX = event.touches[0].clientX;
this.startY = event.touches[0].clientY;
isMoving = false;
};
FastButton.prototype.onTouchMove = function(event) {
if(Math.abs(event.touches[0].clientX - this.startX) > 10 || Math.abs(event.touches[0].clientY - this.startY) > 10) {
this.reset();
}
};
FastButton.prototype.onClick = function(event) {
this.reset();
this.handler(event);
if(event.type == 'touchend') {
preventGhostClick(this.startX, this.startY);
}
};
FastButton.prototype.reset = function() {
this.element.removeEventListener('touchend', this, false);
document.body.removeEventListener('touchmove', this, false);
};
function preventGhostClick(x, y) {
coordinates.push(x, y);
window.setTimeout(gpop, 2500);
};
function gpop() {
coordinates.splice(0, 2);
};
function gonClick(event) {
for(var i = 0; i < coordinates.length; i += 2) {
var x = coordinates[i];
var y = coordinates[i + 1];
if(Math.abs(event.clientX - x) < 25 && Math.abs(event.clientY - y) < 25) {
event.stopPropagation();
event.preventDefault();
}
}
};
document.addEventListener('click', gonClick, true);
var coordinates = [];
function initFastButtons() {
new FastButton(document.getElementById("fastclick"), goSomewhere);
};
function goSomewhere() {
var theTarget = document.elementFromPoint(this.startX, this.startY);
if(theTarget.nodeType == 3) theTarget = theTarget.parentNode;
var theEvent = document.createEvent('MouseEvents');
theEvent.initEvent('click', true, true);
theTarget.dispatchEvent(theEvent);
};
//========================================================
Ben Howdle最近创建了一个开源项目Touche.js,它以一种相当简单和优雅的方式解决了这个问题。对于寻求解决此问题的任何人来说,可能值得一看。
这对我有用。每当将新页面添加到 dom 中时,我们就可以将快速点击附加到所有链接...
// when new pages are loaded into the DOM via JQM AJAX Nav, apply ko bindings to that page's DOM
$(document).on('pageinit', '.ui-page', function (event, data)
{
var activePage = $(event.target).get(0);
FastClick.attach(activePage);
});
我无法直接对 MikeZ 的推荐发表评论。
我成功地使用了它,但不得不做一些额外的 tweek,尤其是对于 android 设备。
而不是调用event.preventDefault();
gonClick(),我还必须调用event.stopImmediatePropagation();
否则,您可能会遇到麻烦,尤其是当动态元素(例如面板)在您单击的元素之上打开时。
与 MikeZ 解决方案一起使用的完整 gonClick() 方法:
function gonClick(event) {
for ( var i = 0; i < coordinates.length; i += 2) {
var x = coordinates[i];
var y = coordinates[i + 1];
if (Math.abs(event.clientX - x) < 25 && Math.abs(event.clientY - y) < 25) {
event.stopPropagation();
event.preventDefault();
event.stopImmediatePropagation();
}
}
};