0

HammerJS の内部イベント ループにスタックしたイベントが残り、その後の検出が台無しになると思われる奇妙な問題に直面しています。

これは、PointerEvents を使用するタッチ デバイス上の Internet Explorer Edge でのみ発生します。

PAN基本的に、イベント ( panstart-> panmove-> panend) にHammerJS を使用し、現在のフレーム境界を越えて(たとえば、IFRAME に入る、またはブラウザー ウィンドウのすぐ外側に) 、そこで指を離すと、HammerJS は CANCEL を受け取りません。イベントとセッションの種類はスタックしたままです。

それ以降、使用しているよりも 1 本多い指 (「ポインター」) で、すべてのジェスチャーが正しく報告されません。

このゴースト状態になった後に Hammer Manager をリセットする方法が見つかりませんでした。これは私のアプリを壊します。

完全に機能する例を含む Fiddle を用意しました。Windows/Touch デバイスで実行してください。

ここに画像の説明を入力

https://jsfiddle.net/28cxrupv/5/

範囲外のイベントを検出する方法、またはスタックしたイベントがあることを他の方法で検出できる場合、Hammer Manager インスタンスを手動でリセットする方法を知りたいです。

アップデート

調査の結果、問題は HammerJS の最も低いレベルにあることがわかりました。PointerEvents ハンドラーには、検出されたポインターの配列がthis.storeあり、古いタイムスタンプを持つスタック イベントがあります。

4

1 に答える 1

0

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 = []);
        },
于 2016-02-25T18:50:22.397 に答える