1

由于我在使用不同的触摸事件库(如hammer.js 和quo.js)时遇到了一个非常奇怪的问题,我决定自己开发我需要的事件。我正在谈论的问题是,如果在我触摸屏幕的位置出现超链接,则触摸会被识别两次。这发生在 iOS 和 Android 上。

想象一下网页上的一个元素,如果你触摸它,它会在视觉上改变屏幕的内容。如果新页面<a href="">在触发新超链接之前在我触摸屏幕的同一位置显示超链接 ( )。

现在我开发了自己的实现,我注意到:我遇到了同样的问题!现在的问题是:为什么?

我所做的是以下(是的,我正在使用 jQuery):

(见下面#1的源代码)

  • 此功能仅与一些特殊元素一起使用,而不是超链接。所以超链接仍然具有默认行为。
  • 该问题仅影响超链接。它不会发生在使用上面显示的事件方法的其他元素上。

所以我可以想象在我触摸的同一个元素上不会触发点击事件,而是在处理触摸事件后在我触摸屏幕的同一位置执行点击“动作”。至少这是它的感觉。因为我只捕捉到我实际触摸的元素上的点击事件,所以我没有捕捉到超链接上的点击事件——实际上这不应该是必要的。

有谁知道是什么导致了这种行为?


完整的源代码

#1 - 将事件附加到元素

$elements是由 $( selector ) 返回的 jQuery 对象;
callback是检测到点击时应调用的函数

helper.registerTapEvent = function($elements, callback) {
    var touchInfo = {
        maxTouches: 0
    };

    function evaluate(oe) {
        var isSingleTouch = touchInfo.maxTouches === 1,

        positionDifferenceX = Math.abs(touchInfo.startX - touchInfo.endX),
        positionDifferenceY = Math.abs(touchInfo.startY - touchInfo.endY),
        isAlmostSamePosition = positionDifferenceX < 15 && positionDifferenceY < 15,

        timeDifference = touchInfo.endTime - touchInfo.startTime,
        isShortTap = timeDifference < 350;

        if (isSingleTouch && isAlmostSamePosition && isShortTap) {
            if (typeof callback === 'function') callback(oe);
        }
    }

    $elements
    .on('touchstart', function(e) {
        var oe = e.originalEvent;

        touchInfo.startTime = oe.timeStamp;
        touchInfo.startX = oe.changedTouches.item(0).clientX;
        touchInfo.startY = oe.changedTouches.item(0).clientY;
        touchInfo.maxTouches = oe.changedTouches.length > touchInfo.maxTouches ? oe.touches.length : touchInfo.maxTouches;
    })
    .on('touchend', function(e) {
        var oe = e.originalEvent;

        oe.preventDefault();

        touchInfo.endTime = oe.timeStamp;
        touchInfo.endX = oe.changedTouches.item(0).clientX;
        touchInfo.endY = oe.changedTouches.item(0).clientY;

        if (oe.touches.length === 0) {
            evaluate(oe);
        }
    })
    .on('click', function(e) {
        var oe = e.originalEvent;

        oe.preventDefault();
    });
}

#2 - 如何完成页面转换的部分

$subPageElem是应该显示的页面的 jQuery 对象,
$subPageElem.prev()返回当前页面的元素,当新页面出现时(暂时)隐藏。

$subPageElem.css({
    webkitTransform: 'translate3d(0,0,0)',
    transform: 'translate3d(0,0,0)'
}).prev().css({
    webkitTransform: 'translate3d(-5%,0,-100px)',
    transform: 'translate3d(-5%,0,-100px)'
});

我还应该提到,新页面$subPageElem是动态生成的并插入到 DOM 中。IE。当我触摸/释放屏幕时,被触发(但不应该)的链接甚至不存在于 DOM 中。

4

0 回答 0