モバイルでも表示可能で、タッチスタートとマウスダウンの両方でアクションをバインドする必要があるWebサイトで作業しています。
こんな感じ
$("#roll").bind("mousedown touchstart", function(event){
someAction();
Iphoneでは正常に動作しますが、Androidでは2回応答します。
event.stopPropagation();
event.preventDefault();
このコードを追加すると、Android Chromeで修正されましたが、Androidデフォルトブラウザでは修正されません。
私はこの機能を使用しています:
//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);
更新:マウスイベントとタッチイベントを一緒にサポートするように回答を変更しました。
element.on('touchstart mousedown', function(e) {
e.preventDefault();
someAction();
});
preventDefault
はイベントをキャンセルします。 仕様による
touchstartを取得しますが、キャンセルするとmousedownを取得できなくなります。受け入れられた答えが言っていることとは反対に、必要なものでない限り、stopPropagation
を呼び出す必要はありません。イベントはキャンセルされた場合でも正常に伝播します。ブラウザはそれを無視しますが、フックは引き続き機能します。
Mozilla 私に同意します これについて:
タッチスタートまたはシリーズの最初のtouchmoveイベントでpreventDefault()を呼び出すと、対応するマウスイベントが発生しなくなります
[〜#〜] edit [〜#〜]:もう一度質問を読みましたが、あなたはすでにこれをやっていて修正されなかったと言いますAndroidデフォルトのブラウザ。受け入れられた回答が基本的に同じことをするので、より複雑な方法でイベント伝播バグ(touchstartは伝播しませんが、クリックします)
win8とchrome/firefoxのgregersのコメントを考慮すると、skyisredのコメントは結局その馬鹿げたものには見えません(:P @ all the 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
}
}
ところで、マウスイベントは常にトリガーされないことがわかりました(stopPropagationとpreventDefaultが使用された場合)、特にタッチエンドイベントの直前に余分なmousemmoveに気づいただけです...本当に奇妙なバグですが、上記のコードはそれをすべて修正しました( OSX、Win、iOS 5 + 6、Android 2 + 4をそれぞれネイティブブラウザー、Chrome、Firefox、IE、Safari、Opera(使用可能な場合)プラットフォームでテスト済み。
このコードを使用して修正
var mobile = /Android|webOS|iPhone|iPad|iPod|BlackBerry/i.test(navigator.userAgent);
var start = mobile ? "touchstart" : "mousedown";
$("#roll").bind(start, function(event){
最善の方法は次のとおりです。
var hasTouchStartEvent = 'ontouchstart' in document.createElement( 'div' );
document.addEventListener( hasTouchStartEvent ? 'touchstart' : 'mousedown', function( e ) {
console.log( e.touches ? 'TouchEvent' : 'MouseEvent' );
}, false );
うわー、これと関連する質問には非常に多くの回答がありましたが、それらのどれも私にとってはうまくいきませんでした(Chrome、mobil responsive、mousedown + touchstart)。でも、これ:
(e) => {
if(typeof(window.ontouchstart) != 'undefined' && e.type == 'mousedown') return;
// do anything...
}
このネイティブソリューションは私に最適です。
touchstart
イベントをドキュメント設定にグローバル_touch = true
_に追加します。if (touch && e.type === 'mousedown') return;
このコードを記述し、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);
}
jquery-fast-click を試すことをお勧めします。この質問と others で他のアプローチを試しました。それぞれが1つの問題を修正し、別の問題を導入しました。高速クリックは、Android、iOS、デスクトップ、デスクトップタッチブラウザーで初めて機能しました(うめき声)。