在一个也可以在移动设备上查看的网站工作,并且需要在touchstart和鼠标按下时绑定操作。
看起来像这样
$("#roll").bind("mousedown touchstart", function(event){
someAction();
它在iPhone上工作正常,但在Android上它会响应两次。
event.stopPropagation();
event.preventDefault();
添加此代码修复了Android Chrome,但不适用于Android默认浏览器。还有其他技巧可以解决所有安卓的问题吗?
element.on('touchstart mousedown', function(e) {
e.preventDefault();
someAction();
});
preventDefault
根据规格取消事件
您可以获得触摸启动,但是一旦取消它,您将不再按下鼠标。与公认的答案相反,除非你需要,否则你不需要打电话给stopPropagation
。即使取消,事件也会正常传播。浏览器会忽略它,但你的钩子仍然可以工作。
Mozilla同意我的观点:
在触摸启动或系列的第一个触摸移动事件上调用 preventDefault() 可防止相应的鼠标事件触发
编辑:我刚刚再次阅读了这个问题,你说你已经这样做了,但它没有修复Android默认浏览器。不确定接受的答案如何提供帮助,因为它基本上做同样的事情,只是以更复杂的方式和事件传播错误(touchstart 不会传播,但单击可以)
我一直在使用这个函数:
//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@所有仇恨者)虽然我宁愿使用黑名单而不是他建议的白名单,只将 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
}
}
顺便说一句:我发现鼠标事件并不总是被触发(如果使用 stopPropagation 和 preventDefault),特别是我只注意到在触摸结束事件之前直接有一个额外的鼠标移动......真的很奇怪的错误,但上面的代码在所有(测试的 OSX、Win、iOS 5+6、Android 2+4 每个平台都使用本机浏览器、Chrome、Firefox、IE、Safari 和 Opera(如果有))平台上为我修复了它。
这个和相关问题的答案这么多,但没有一个对我有用(Chrome、移动响应、鼠标按下 + 触摸启动)。但是这个:
(e) => {
if(typeof(window.ontouchstart) != 'undefined' && e.type == 'mousedown') return;
// do anything...
}
这是一个非常古老的问题,但我遇到了同样的问题,并找到了另一种不stopPropagation()
、preventDefault()
或嗅探设备类型的解决方案。我使用此解决方案时,假设设备同时支持触摸和鼠标输入。
说明:启动触摸时,事件的顺序为 1) touchstart
2) touchmove
3) touchend
4) mousemove
5) mousedown
6) mouseup
7) click
.基于此,我们将标记从touchstart
(链中的第一个)到click
(链中的最后一个)的触摸交互。如果在此触摸交互之外注册了mousedown
,则可以安全地拾取。
下面是 Dart 中的逻辑,在 js 中应该非常可复制。
var touchStarted = false;
document.onMouseDown.listen((evt) {
if (!touchStarted) processInput(evt);
});
document.onClick.listen((evt) {
touchStarted = false;
});
document.onTouchStart.listen((evt) {
touchStarted = true;
processInput(evt);
});
如您所见,我的听众被放置在document
.因此,至关重要的是,我不能stopPropagation()
或preventDefault()
这些事件,这样它们就可以冒出其他元素。这个解决方案帮助我挑选出一个互动来采取行动,希望它也能帮助你!
使用此代码修复
var mobile = /Android|webOS|iPhone|iPad|iPod|BlackBerry/i.test(navigator.userAgent);
var start = mobile ? "touchstart" : "mousedown";
$("#roll").bind(start, function(event){
建议你尝试jquery-fast-click。我在这个问题和其他问题上尝试了另一种方法。每个人都修复了一个问题,并引入了另一个问题。快速点击首次在Android,ios,桌面和桌面触摸浏览器上工作(呻吟)。
编写此代码并添加 j 查询冲孔触摸 js.it 将工作 使用触摸事件模拟鼠标事件
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);
}
这个本机解决方案最适合我:
- 将
touchstart
事件添加到文档设置全局touch = true
。
在鼠标按下 - /触摸启动处理程序中,防止检测到触摸屏时的所有鼠标按下事件:
if (touch && e.type === 'mousedown') return;
我认为最好的方法是:
var hasTouchStartEvent = 'ontouchstart' in document.createElement( 'div' );
document.addEventListener( hasTouchStartEvent ? 'touchstart' : 'mousedown', function( e ) {
console.log( e.touches ? 'TouchEvent' : 'MouseEvent' );
}, false );