Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/461.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/219.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何绑定Mousedown和Touchstart,但不同时响应两者?Android,JQuery_Javascript_Android_Jquery - Fatal编程技术网

Javascript 如何绑定Mousedown和Touchstart,但不同时响应两者?Android,JQuery

Javascript 如何绑定Mousedown和Touchstart,但不同时响应两者?Android,JQuery,javascript,android,jquery,Javascript,Android,Jquery,在手机上也可以查看的网站上工作,并且需要在touchstart和mousedown上绑定操作 看起来像这样 $("#roll").bind("mousedown touchstart", function(event){ someAction(); 它在Iphone上运行良好,但在Android上会有两次响应 event.stopPropagation(); event.preventDefault(); 添加此代码修复了Android Chrome,但不适用于Android默认浏览器

在手机上也可以查看的网站上工作,并且需要在touchstart和mousedown上绑定操作

看起来像这样

 $("#roll").bind("mousedown touchstart", function(event){

 someAction();
它在Iphone上运行良好,但在Android上会有两次响应

event.stopPropagation();
event.preventDefault();
添加此代码修复了Android Chrome,但不适用于Android默认浏览器。还有其他可以解决所有安卓系统问题的技巧吗

使用此代码修复

var mobile   = /Android|webOS|iPhone|iPad|iPod|BlackBerry/i.test(navigator.userAgent); 
var start = mobile ? "touchstart" : "mousedown";
$("#roll").bind(start, function(event){

我一直在使用此功能:

//touch click helper
(function ($) {
    $.fn.tclick = function (onclick) {

        this.bind("touchstart", function (e) { 
            onclick.call(this, e); 
            e.stopPropagation(); 
            e.preventDefault(); 
        });

        this.bind("click", function (e) { 
           onclick.call(this, e);  //substitute mousedown event for exact same result as touchstart         
        });   

        return this;
    };
})(jQuery);

更新:修改答案以支持鼠标和触摸事件

考虑到格雷格对win8和chrome/firefox的评论,skyisred的评论看起来并没有那么愚蠢(:p@all haters) 尽管我宁愿选择黑名单,也不愿选择他建议的白名单,只是将Android排除在触摸绑定之外:

var ua = navigator.userAgent.toLowerCase(),
isAndroid = ua.indexOf("android") != -1,
supportsPointer = !!window.navigator.msPointerEnabled,
ev_pointer = function(e) { ... }, // function to handle IE10's pointer events
ev_touch = function(e) { ... }, // function to handle touch events
ev_mouse = function(e) { ... }; // function to handle mouse events

if (supportsPointer) { // IE10 / Pointer Events
    // reset binds
    $("yourSelectorHere").on('MSPointerDown MSPointerMove MSPointerUp', ev_pointer);
} else {
    $("yourSelectorHere").on('touchstart touchmove touchend', ev_touch); // touch events
    if(!isAndroid) { 
        // in androids native browser mouse events are sometimes triggered directly w/o a preceding touchevent (most likely a bug)
        // bug confirmed in android 4.0.3 and 4.1.2
        $("yourSelectorHere").on('mousedown mousemove mouseup mouseleave', ev_mouse); // mouse events
    }
}
顺便说一句:我发现鼠标事件并不总是被触发(如果使用了StopRopagation和preventDefault),特别是我只注意到在touchend事件之前有一个额外的鼠标移动。。。非常奇怪的bug,但上面的代码为我修复了所有平台(测试了OSX、Win、iOS 5+6、Android 2+4,每个平台都有本机浏览器、Chrome、Firefox、IE、Safari和Opera,如果有的话)。

我建议你试试。在这个问题上,我尝试了另一种方法,结果失败了。每个都解决了一个问题,并引入了另一个问题。快速点击在Android、ios、桌面和桌面触摸浏览器(groan)上首次奏效

preventDefault
取消事件

您将获得touchstart,但一旦取消它,您将不再被鼠标按下。与公认的答案相反,您不需要调用
stopPropagation
,除非您需要它。即使取消,事件也将正常传播。浏览器将忽略它,但钩子仍然可以工作

Mozilla关于这一点:

对touchstart或系列的第一个touchmove事件调用preventDefault()可防止触发相应的鼠标事件


编辑:我刚刚又读了一遍问题,你说你已经这么做了,但没有修复Android默认浏览器。不确定接受的答案有何帮助,因为它基本上做了相同的事情,只是以更复杂的方式和事件传播错误(touchstart不会传播,但单击会传播)

编写此代码并添加j query punch touch js。它将使用触摸事件模拟鼠标事件

function touchHandler(event)
{
    var touches = event.changedTouches,
        first = touches[0],
        type = "";
         switch(event.type)
    {
        case "touchstart": type = "mousedown"; break;
        case "touchmove":  type="mousemove"; break;        
        case "touchend":   type="mouseup"; break;
        default: return;
    }

    var simulatedEvent = document.createEvent("MouseEvent");
    simulatedEvent.initMouseEvent(type, true, true, window, 1, 
                              first.screenX, first.screenY, 
                              first.clientX, first.clientY, false, 
                              false, false, false, 0/*left*/, null);
    first.target.dispatchEvent(simulatedEvent);
    event.preventDefault();
}

function init() 
{
    document.addEventListener("touchstart", touchHandler, true);
    document.addEventListener("touchmove", touchHandler, true);
    document.addEventListener("touchend", touchHandler, true);
    document.addEventListener("touchcancel", touchHandler, true);    
} 

我认为最好的办法是:

var hasTouchStartEvent = 'ontouchstart' in document.createElement( 'div' );

document.addEventListener( hasTouchStartEvent ? 'touchstart' : 'mousedown', function( e ) {
    console.log( e.touches ? 'TouchEvent' : 'MouseEvent' );
}, false );

本机解决方案最适合我:

  • touchstart
    事件添加到文档设置全局
    touch=true
  • 在mousedown/touchstart处理程序中,当检测到触摸屏时,防止所有mousedown事件:
    if(touch&&e.type==“mousedown”)返回

  • 哇,这个问题和相关问题有这么多答案,但没有一个对我有用(Chrome、mobil responsive、mousedown+touchstart)。但这是:

    (e) => {
      if(typeof(window.ontouchstart) != 'undefined' && e.type == 'mousedown') return;
    
      // do anything...
    }
    

    -1:使用特征检测(如Joshua的答案)而不是特征检测。这是最好的答案,也是唯一有效的答案。Joshua的回答没有使用特征检测。你需要检测的唯一特性是android当前的怪癖。如果检测到具有触摸事件的功能,则将禁用触摸屏笔记本电脑的鼠标。e、 preventDefault()在android上失败。同时使用触摸和鼠标的设备如何?这也不能正常工作。我已经测试了类范围,没有范围,那么每种方法都有自己的问题。在类作用域中使用此代码只会触发
    mousedown
    ,无论您如何尝试使用
    touchstart
    mousedown
    触发该函数。如果没有范围,它会不断触发您第一次触发的一个结果。请注意,Windows 8上的Chrome和Firefox将在检测到触摸屏时启用触摸事件。因此,用户可以在鼠标和触摸输入之间切换。使用此代码,鼠标事件将被忽略。@gregers您是对的,您是错的。Windows 8确实支持触摸和鼠标事件,但触摸时,您可以取消“虚拟”鼠标事件以仅处理触摸,它不会影响真正的鼠标事件,因为它们不会触发触摸事件。@daniel.gindi我的评论是针对这个答案的上一个版本:
    touchstart
    相当于
    mousedown
    而不是
    click
    。单击需要用户按下按钮。我不明白这怎么会有完全相同的结果。你会如何解开这个事件?假设您想临时添加侦听器,然后停止触发事件?event.preventDefault()应该停止mousedown事件。这个问题由来已久,希望现在能解决。我也遇到了同样的问题,结果证明是jquery touchpunch造成了这个问题。这个同样的问题可能对其他人的帮助大于这里的答案:那么我的鼠标在我的触摸屏笔记本电脑上就不能工作了。如果你为mousedown添加了另一个事件,android会在触摸屏上触发这两个事件。大多数新笔记本电脑也支持触摸屏,所以会有这些事件。。别这样!在android上,我得到“忽略尝试取消cancelable=false的touchmove事件,例如,因为滚动正在进行且无法中断”,您可能需要addEventListener('touchstart',函数,{passive:false});这是可行的,但是你甚至不能通过滑动来滚动页面。这太冗长了,你能想象每次IE发布新版本时都能保持这些吗?实用的解决方案:)
    (e) => {
      if(typeof(window.ontouchstart) != 'undefined' && e.type == 'mousedown') return;
    
      // do anything...
    }