Javascript 如何绑定Mousedown和Touchstart,但不同时响应两者?Android,JQuery
在手机上也可以查看的网站上工作,并且需要在touchstart和mousedown上绑定操作 看起来像这样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默认浏览器
$("#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
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...
}