Hammer.JS にパッチを適用してスタック ポインターを検出できるようにする方法を見つけました。これが間違っているかどうかはわかりませんが、明らかにうまくいきます!
HammerJS PointerEvents ハンドラーには、this.store
現在のすべてのポインター イベントを保持する配列があります。ウィンドウからパンアウトしてタッチを離すと、スタックしたイベントが永久に保持されます。
この配列をクリアすると、Hammer は再び通常の状態に戻ります。
プライマリ タッチ (ジェスチャの開始?) を処理していて、ストアが空でない場合、ストアが自動的にクリアされるという条件を追加しました。
それがどのように機能するかというと、スタックしたハンマー インスタンスとの次の対話で、内部ストアがリセットされ、ジェスチャが適切に解釈されます。
Hammer.js 2.0.6 では、885 行目あたり
/**
* handle mouse events
* @param {Object} ev
*/
handler: function PEhandler(ev) {
var store = this.store;
var removePointer = false;
var eventTypeNormalized = ev.type.toLowerCase().replace('ms', '');
var eventType = POINTER_INPUT_MAP[eventTypeNormalized];
var pointerType = IE10_POINTER_TYPE_ENUM[ev.pointerType] || ev.pointerType;
var isTouch = (pointerType == INPUT_TYPE_TOUCH);
// get index of the event in the store
var storeIndex = inArray(store, ev.pointerId, 'pointerId');
// start and mouse must be down
if (eventType & INPUT_START && (ev.button === 0 || isTouch)) {
// NEW CONDITION: Check the store is empty on a new gesture
// http://stackoverflow.com/questions/35618107/cross-frame-events-on-ie-edge-break-hammerjs-v2
if (ev.isPrimary && store.length) {
window.console.warn ("Store should be 0 on a primary touch! Clearing Stuck Event!");
this.reset();
}
if (storeIndex < 0) {
store.push(ev);
storeIndex = store.length - 1;
}
} else if (eventType & (INPUT_END | INPUT_CANCEL)) {
removePointer = true;
}
// it not found, so the pointer hasn't been down (so it's probably a hover)
if (storeIndex < 0) {
return;
}
// update the event in the store
store[storeIndex] = ev;
this.callback(this.manager, eventType, {
pointers: store,
changedPointers: [ev],
pointerType: pointerType,
srcEvent: ev
});
if (removePointer) {
// remove from the store
store.splice(storeIndex, 1);
}
}
});
また、関数「リセット」を定義します。
/**
* Reset internal state
*/
reset: function() {
this.store = (this.manager.session.pointerEvents = []);
},