检测用户在触屏设备上是想点击还是滚动页面的意图。

4

如果用户在弹出框之外点击(touchstart),我希望隐藏弹出框。

但如果用户的意图是滚动/划动屏幕(touchmove),我不想隐藏弹出框。

如何编写代码来检测和响应这两个操作(使用或不使用jQuery)?


2
尝试检测长按以进行滑动操作,短按以进行触摸操作。 - Akshay Khandelwal
你能举个例子吗?那会是什么样子的? - Fellow Stranger
3个回答

3

这是一个如何实现此操作的基本示例: http://jsfiddle.net/4CrES/2/

它背后的逻辑涉及检测初始触摸时间并将其保存到变量中。

touchTime = new Date();

在touchend处理程序中,从当前时间减去此时间以获取差异:
var diff = new Date() - touchTime;

使用if语句来判断触摸持续时间是够短以被看作是轻点,还是长到足以被视为拖动。
if (diff < 100){
    //It's a tap
}
else {
    //Not a quick tap
}

你可以通过处理程序中初始触摸y位置与最终触摸y位置的差异来编写更强大的实现。另一个选项是比较滚动区域的scrollTop,以查看它是否已经滚动。

2
已更新fiddle http://jsfiddle.net/4CrES/3/,使其在浏览器上的工作方式与移动设备上相同。因此,添加了mousedown(在触摸设备上为touchstart)和mouseup(在触摸设备上为touchend)事件,以便在浏览器中观察到相同的效果。 - Akshay Khandelwal

0

由于在移动Safari上,点击事件不会冒泡到DOM,而触摸事件和自定义事件会冒泡,因此我最近编写了一些代码来检测快速点击。

当触摸事件开始和结束时没有沿着屏幕移动,没有滚动发生,并且所有操作在200毫秒内完成时,就是一个快速点击。

如果确定触摸是“快速点击”,则TouchManager会导致DOM中的触摸元素发出自定义的“quickTap”事件,然后该事件会冒泡到任何其他正在监听它的元素。这段代码定义并创建了触摸管理器,它将立即准备就绪。

缺点:

  • 使用jQuery
  • 只考虑了单指操作。
  • 还从modernizr借用了一些代码。(如果您已经包含Modernizr,则可以省略该部分。)

也许这有点过度,但它是我正在开发的较大代码库的一部分。

/** 
 * Click events do not bubble up the DOM on mobile Safari unless the click happens on a link or form input, but other events do bubble up.
 * The quick-tap detects the touch-screen equivalent of a click and triggers a custom event on the target of the tap which will bubble up the DOM.
 * A touch is considered a click if there is a touch and release without any movement along the screen or any scrolling.
 */

var qt = (function ($) {
    /**
     * Modernizr 3.0.0pre (Custom Build) | MIT 
     * Modernizr's touchevent test
     */
    var touchSupport = (function() {
            var bool,
                prefixes = ' -webkit- -moz- -o- -ms- '.split(' ')
            if(('ontouchstart' in window) || window.DocumentTouch && document instanceof DocumentTouch) {
                bool = true;
            } else {
                var query = ['@media (',prefixes.join('touch-enabled),('),'heartz',')','{#modernizr{top:9px;position:absolute}}'].join('');
                testStyles(query, function( node ) {
                    bool = node.offsetTop === 9;
                });
            }
            return bool;
        }()),
        MobileTapEvent = 'tapEvent';

    if(touchSupport) {
        /* Create a new qt (constructor)*/
        var startTime = null,
            startTouch = null,
            isActive = false,
            scrolled = false;

        /* Constructor */
        function qt() {
            var _qt = this,
                context = $(document);
            context.on("touchstart", function (evt) {
                startTime = evt.timeStamp;
                startTouch = evt.originalEvent.touches.item(0);
                isActive = true;
                scrolled = false;
            })
            context.on("touchend", function (evt) {
                window.ct = evt.originalEvent['changedTouches'];
                // Get the distance between the initial touch and the point where the touch stopped.
                var duration = evt.timeStamp - startTime,
                    movement = _qt.getMovement(startTouch, evt.originalEvent['changedTouches'].item(0)), 
                    isTap = !scrolled && movement < 5 && duration < 200;
                if (isTap) {
                    $(evt.target).trigger('quickTap', evt);
                }
            })
            context.on('scroll mousemove touchmove', function (evt) {
                if ((evt.type === "scroll" || evt.type === 'mousemove' || evt.type === 'touchmove') && isActive && !scrolled) {
                    scrolled = true;
                }
            });
        }

        /* Calculate the movement during the touch event(s)*/
        qt.prototype.getMovement = function (s, e) {
            if(!s || !e) return 0;
            var dx = e.screenX - s.screenX, 
                dy = e.screenY - s.screenY;
            return Math.sqrt((dx * dx) + (dy * dy));
        };
        return new qt();
    }
}(jQuery));

要使用这段代码,您需要将其添加到您的页面中,然后只需监听 quickTap 事件即可。

<script type="text/javascript" src="http://code.jquery.com/jquery-2.0.3.min.js"></script>
<script type="text/javascript" src="quick-tap.js"></script>
<script type="text/javascript">
    $(document).on('quickTap', function(evt, originalEvent) {
        console.log('tap event detected on: ', evt.target.nodeName, 'tag');
    });
</script>

evt 是 quickTap 事件。

evt.target 是被点击的 DOM 元素(不是 jQuery 对象)。

originalEvent 是 touchend 事件,qt 在其中确定它是否为轻触事件。


0

您可以在touchend事件中隐藏弹出式div。
touchstart事件中,您需要记住window.scrollY的值。
touchend事件中,如果scrollY位置不同,则用户已经滚动。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接