ニースの質問! +1
この問題はFastClickとは関係ありませんが、FastClickは問題の解決をより複雑にします。したがって、私は純粋なJavaScriptと生のタッチイベントに固執するでしょう)
モバイルタッチデバイスでは、webviewの実装は、プラットフォーム固有の理由でデスクトップのWebブラウザと大きく異なります。 この場合重要な機能の1つは、Webビューでのモーメンタムスクロールです。 モーメンタムスクロールは、デバイスのハードウェアアクセラレーション機能です。スクロール可能領域に画面がタッチされると、ハードウェアはタッチを識別し、スクロール可能な領域に200ミリ秒のカウントダウンタイマーを付加します。トリガーされると、領域がハードウェアアクセラレーションされたスクロールになります。ハードウェアが状態にあるとき、ハードウェアアクセラレーションされたスクロールに固有のものであるため、タッチイベントをブロードキャストしません。タイマーをキャンセルし、200ミリ秒以内にtouchイベントのpreventDefaultを使用してモーメンタムスクロールを防止しました。
ここで私はこの問題に近づいています。たとえば、overflow:scroll
というネイティブスクロールを使用しているとします。 このメソッドは、タッチ可能な要素にtouchstart
イベントをアタッチすることです。 touchstart
イベントが発生すると、イベントハンドラは、touchend
,touchmove
、およびtouchcancel
イベントをターゲット要素に関連付けます。 140ms後に新たに追加されたイベントを削除するsetTimoutタイマーが開始されます。ここで
は私の生産コードのためのいくつかのクリップです: 私はコレクションからイベントを追加および削除する2つのイベントメソッドがあります:
:
var eventify = (function() {
function eventify(type, el, callback, phase) {
phase = phase || false;
if ((el.constructor.toString().contains('NodeList')) || (el.constructor.toString().contains('HTMLCollection'))) {
[].forEach.call(el, function (element) {
if (!element.hasEvent(type)) {
element.addEvent(type);
HTMLElement.prototype.addEventListener.apply(element, [type, callback, phase]);
}
});
} else {
if (!el.hasEvent(type)) {
el.addEvent(type);
HTMLElement.prototype.addEventListener.apply(el, [type, callback, phase]);
}
}
return callback;
}
return eventify
})();
var uneventify = (function() {
function uneventify(type, el, callback) {
if ((el.constructor.toString().contains('NodeList')) || (el.constructor.toString().contains('HTMLCollection'))) {
[].forEach.call(el, function (element) {
if (element.hasEvent(type)) {
element.removeEvent(type);
HTMLElement.prototype.removeEventListener.apply(element, [type, callback]);
}
});
} else {
if (el.hasEvent(type)) {
el.removeEvent(type);
HTMLElement.prototype.removeEventListener.apply(el, [type, callback]);
}
}
}
return uneventify
})();
をそれから私は、スクロールのタップイベントのtapify方法を持っています
var tapify = (function() {
function tapify(el, callback) {
eventify('touchstart', el, function (e) {
var that = this;
var start = e.pageY;
var target = e.target;
function dynamicEvents() {
var endfn = eventify('touchend', target, function (evt) {
e.preventDefault();
e.stopImmediatePropagation();
evt.preventDefault();
evt.stopImmediatePropagation();
uneventify('touchmove', target, movefn);
uneventify('touchend', target, endfn);
uneventify('touchcancel', target, cancelfn);
callback && callback(target);
});
var cancelfn = eventify('touchcancel', target, function (evt) {
e.preventDefault();
e.stopImmediatePropagation();
evt.preventDefault();
evt.stopImmediatePropagation();
uneventify('touchmove', target, movefn);
uneventify('touchend', target, endfn);
uneventify('touchcancel', target, cancelfn);
callback && callback(target);
});
var movefn = eventify('touchmove', target, function (evt) {
var distance = start - evt.pageY;
if (distance > 20) {
uneventify('touchend', target, endfn);
uneventify('touchcancel', target, cancelfn);
uneventify('touchmove', el, movefn);
}
});
setTimeout(function() {
uneventify('touchmove', target, movefn);
uneventify('touchend', target, endfn);
uneventify('touchcancel', target, cancelfn);
}, 140);
}
if (global.isIos) setTimeout(function() {
dynamicEvents();
}, 60);
else dynamicEvents();
}, false);
}
return tapify;
})();
global.isIosを使用してターゲットデバイスを識別しています。 AndroidはタッチイベントをWebビューアで200ms送信するのをやめます。その後
、要素または要素のコレクションを使用したイベントを添付する:
tapify(document.querySelectorAll('button'), function (e) {
//your event handler here!!
});
希望、これはそれが実際にすべてのコントロールのために働いてからFastClickを妨げる...
感謝を助けます。 –