Travailler sur un site Web qui est également visible sur mobile et qui doit lier une action à la fois au touchstart et au mousedown.
Ressemble à ça
$("#roll").bind("mousedown touchstart", function(event){
someAction();
Cela fonctionne bien sur Iphone, mais sur Android, il répond deux fois.
event.stopPropagation();
event.preventDefault();
L'ajout de ce code a corrigé le problème pour Android Chrome, mais PAS pour le navigateur par défaut Android. D'autres astuces qui peuvent résoudre le problème pour tous les android?
J'ai utilisé cette fonction:
//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);
UPDATE: Réponse modifiée pour prendre en charge les événements de souris et de contact.
element.on('touchstart mousedown', function(e) {
e.preventDefault();
someAction();
});
preventDefault
annule l'événement, conformément aux spécifications
Vous obtenez touchstart, mais une fois que vous l'annulez, vous n'obtenez plus (mousedown). Contrairement à ce que dit la réponse acceptée, vous n'avez pas besoin d'appeler stopPropagation
à moins que vous n'ayez besoin de quelque chose. L'événement se propage normalement même lorsqu'il est annulé. Le navigateur l'ignorera, mais vos crochets continueront à fonctionner.
Mozilla est d'accord avec moi sur celui-ci:
l'appel de preventDefault () sur un touchstart ou le premier événement touchmove d'une série empêche le déclenchement des événements de souris correspondants.
EDIT: Je viens juste de relire la question et vous dites que vous l'avez déjà fait et que cela n'a pas corrigé le navigateur par défaut d'Android. Pas sûr de savoir comment la réponse acceptée a aidé, car elle fait la même chose, d'une manière plus compliquée et avec un bogue de propagation d'événement (touchstart ne se propage pas, mais cliquez si)
en prenant en compte les commentaires de gregers sur win8 et chrome/firefox, le commentaire de skyisred n’a pas l’air bête après tout (: P @ tous les ennemis). exclure Android de touch-binds:
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
}
}
BTW: J'ai constaté que les événements de souris ne sont PAS toujours déclenchés (si stopPropagation et preventDefault étaient utilisés), plus précisément, je n'ai remarqué qu'un déplacement de souris supplémentaire directement avant un événement touchend ... un bug vraiment étrange testé OSX, Win, iOS 5 + 6, Android 2 + 4 avec chacun un navigateur natif, Chrome, Firefox, IE, Safari et Opera, le cas échéant).
Fixé en utilisant ce code
var mobile = /Android|webOS|iPhone|iPad|iPod|BlackBerry/i.test(navigator.userAgent);
var start = mobile ? "touchstart" : "mousedown";
$("#roll").bind(start, function(event){
Je pense que le meilleur moyen est:
var hasTouchStartEvent = 'ontouchstart' in document.createElement( 'div' );
document.addEventListener( hasTouchStartEvent ? 'touchstart' : 'mousedown', function( e ) {
console.log( e.touches ? 'TouchEvent' : 'MouseEvent' );
}, false );
Cette solution native fonctionnait mieux pour moi:
touchstart
aux paramètres du document avec un touch = true
global.if (touch && e.type === 'mousedown') return;
Écrivez ce code et ajoutez une requête j de perforation de requête tactile
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);
}
Je vous recommande d'essayer jquery-fast-click . J'ai essayé l'autre approche sur cette question et autres . Chaque problème corrigé et introduit un autre. fast-click a fonctionné pour la première fois sur les navigateurs tactiles Android, iOS, de bureau et de bureau (groan).