jQuery.on "touchstart mousedown" - 触摸屏设备上会触发两个事件

3
我的问题是在Android原生浏览器中,无法取消触摸开始后触发的mousedown事件。这个问题只出现在Android原生浏览器中。
在Android和iOS上,Chrome和Safari都可以成功执行下面的方法(onMenuInteraction),但我的问题似乎仅限于Android原生浏览器(对我来说是预装在Android 4.1.2中的)。
以下是我从JavaScript对象中提取的代码。
MenuButtonView.prototype.onSmallScreenSetUp = function() {
    $("#mobileMenuBtn").on( { "touchstart mousedown": $.proxy( this.onMenuInteraction, this ) } );
}

MenuButtonView.prototype.onMenuInteraction = function(e) {
    console.log( this, "onMenuInteraction", e );
    e.stopImmediatePropagation();
    e.stopPropagation();
    e.preventDefault();
}

请问有没有办法取消在触发touchstart事件后,手指碰触屏幕导致的mousedown事件?这个问题涉及到在桌面和移动/平板设备上管理交互。在Android原生浏览器上测试时,一切正常,直到出现这个问题。谢谢!
4个回答

10

检查是否支持touchstart事件,设置一个变量来确定您提供的支持:

检测是否支持touchstart事件,并设置一个变量以确定所提供的支持:

//touchstart or mousedown
var click = ('ontouchstart' in document.documentElement)  ? 'touchstart' : 'mousedown';

然后使用:

$(element).on(click,function(){
    //do stuff
}); 

请注意,在这种情况下,click 是一个变量,而不是字符串。


3
在新的同时拥有触摸屏和鼠标的笔记本电脑上,这个功能是如何工作的? - Alec
1
我认为他们使用touchstart,但它们响应像触摸一样的鼠标输入。我几个月前测试过,我确定那就是发生的事情。不过现在我没有这样的设备来测试了。我记得当时我正在构建的东西必须通过MS Surface测试,并且它确实通过了。 - dewd
@CandleCoder,操作系统和浏览器是什么?我在微软Surface上测试过(1年半前),它可以工作。 - dewd
华硕Chromebook - CandleCoder
很不幸,我没有Chromebook来测试,模拟器通常也不可靠。这将是一个逆向工程的案例,然后尝试使其x设备/浏览器兼容。你是否尝试过单独进行其中之一,例如只有touchstart或mousedown?设备对每个单独的响应如何? - dewd
显示剩余2条评论

2

如果触发了touchstart事件,使用e.preventDefault();来取消mousedown事件。


1
唯一可行的解决方案!其他人不理解,因为他们没有同时具备触摸屏和鼠标(例如 Chromebook)的笔记本电脑。谢谢! - FlorianB

1

结合JDA和Dave Methvin的建议(感谢两位),我对我的问题进行了解决。

在“touchstart mousedown”事件的回调中,我专门关闭了“touchstart mousedown”。这样可以阻止任何后续的触摸或鼠标事件被调用。

我发现在Android的原生浏览器中实现“touchend”有问题 - 然而,“mouseup”事件似乎很好地覆盖了这两个目的,即,在我的看来,它的行为方式与您期望的“touchend”相同。

当调用“mouseup”时,我会重新应用“touchstart”和“mousedown”事件到按钮上。

下面是我解决方案的简化版本:

$(document).ready( function() {

        $("#mobileMenuBtn").on( { "touchstart mousedown" : onInteraction,
                                  "mouseup" : onInteractionEnd } );

        function onInteraction(e) {
            $("#mobileMenuBtn").off( "touchstart mousedown" );
        }

        function onInteractionEnd(e) {
            $("#mobileMenuBtn").on( { "touchstart mousedown" : onInteraction } );
        }

})

希望这能帮助到遇到相同问题的其他人。

1
  1. 检测支持哪些事件-不需要同时支持两个事件
  2. 相应地加载$.on()
  3. 在添加事件之前,删除所有传播和/或预先存在的(不需要的)事件,以避免出现问题

    $("#mobileMenuBtn").off().on( { "touchstart mousedown": $.proxy( this.onMenuInteraction, this ) } );

参考资料:

如何使用JS / jQuery检查浏览器是否支持touchstart

jquery:off()


1
关于#1,一般而言这并不正确,一个设备可以同时拥有触摸屏和鼠标设备。例如,Chromebook或Windows触摸屏平板电脑/笔记本电脑。如果这是一个Android应用程序(例如嵌入在Phonegap / Cordova中),那么您可以假设只有触摸事件,并跳过鼠标。如果这是一个网页,您不能假设它,因为它可能会在几个不同的浏览器中访问,包括桌面浏览器。请尝试此操作:https://dev59.com/w2Yr5IYBdhLWcg3wdp8C - Dave Methvin
他特别提到了Android,我回答了他的Android问题;)我同意,在特定的环境下,你可能需要以不同的方式处理事情。 - JDA

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