これは奇妙なものです!
概要:
私はWebアプリを作成しており、Facebookアプリにあるものと同様のメニューを作成しました。右にスワイプすると表示され、左にスワイプすると非表示になります。
これを行うには、タッチスタートイベントをページの本文にバインドします。この時点で、指を押す開始ポイントを記録し、タッチムーブイベントとタッチエンドイベントもバインドします。touch moveイベントは、現在の指の位置を検出し、translate3d(x、y、z)を指の位置に一致するように設定することにより、ページコンテンツを含むdivを移動します。
それは実際に本当に素晴らしい働きをします。
次に、タッチエンドで、指がメニューの表示をトリガーするのに十分な距離まで移動したのか、コンテンツが元の位置に戻るのに十分な距離に移動したのかを調べます。選択に関係なく、コンテンツdivに-webkit-transition:-webkit-transformなどを適用するクラスを適用します。次に、もう一度translate3d(x、y、z)を使用して、決定された終了位置を設定し、それ以上のタップが一時的に機能しないようにする変数も設定します。
そして、これは問題があるところです!
問題:
この時点で、コンテンツが基本構造、つまり記事のレイアウトページで単純な場合、移行は迅速かつ瞬時に行われます。でも!コンテンツが複雑な場合、つまりデータのテーブルが大きい場合は、1〜30秒の範囲で一時停止が発生します...非常にイライラします。
最終的に機能する場合、コールバックは本体からtouchmoveイベントとtouchendイベントのバインドを解除し、タップを停止する変数が設定解除され、再開する準備が整います。
私はiPad1でテストしています。スワイプの速度と一時停止の長さの間に相関関係はないようです。また、コンテンツが移動するために残された距離の間に何もありません。
最後に、これが鍵だと思います!
同じ開閉アクションを自動的に実行するボタンがあり(これもFacebookのように)、正常に機能します。スワイプすると一時停止し、そのボタンをタップすると、ベースが切り替わるときに間違った方向ではありますが、すぐに機能し始めます。すでに開くように設定されている変数。ある種のアニメーションキューをクリアして、それ自体を整理するようなものです...
いくつかのコード:
javascript
$body.bind({
'touchstart': function(e){
if( !swipeBan ){
// Reset
var used = false,
triggered = false,
dir = false;
// Get start point
start.x = e.originalEvent.touches[0].pageX;
start.y = e.originalEvent.touches[0].pageY;
$body.bind({
'touchmove': function(e){
// Get current value (will be the end value too)
end.x = e.originalEvent.touches[0].pageX;
end.y = e.originalEvent.touches[0].pageY;
// If we have not chosen a direction, choose one
if( !dir ){
dir = getDir();
}else{
var left = open && dir == 'left',
right = !open && dir == 'right';
if( left || right ){
var x = left ? maxSwipe - getDist('left') : getDist('right');
$content.setTransform(x);
used = true;
triggered = left ? maxSwipe - x > swipeTrigger : x > swipeTrigger;
e.preventDefault();
}
}
},
'touchend': function(e){
// Only go further if we are going the correct direction
if( used ){
swipeBan = true;
// Get ready for animation
function done(){
// Get touching!
swipeBan = false;
// Stop animating
$content.removeClass('animate');
}
// Add animate class
$content.addClass('animate');
// Set the value
if( ( !open && triggered ) || ( open && !triggered ) ){
$content.setTransform(maxSwipe,0,function(){
done();
});
$body.removeClass('closed');
open = true;
}else if( ( !open && !triggered ) || ( open && triggered ) ){
$content.setTransform(0,0,function(){
done();
});
$body.addClass('closed');
open = false;
}
}
// Unbind everything
$body.unbind('touchmove touchend');
}
});
}else{
e.preventDefault();
}
}
});
上で使用したsettransformプラグイン。
$.fn.setTransform = function(x,y,callback){
y = y ? y : '0';
var $this = $(this);
if( callback ){
$this.one('webkitTransitionEnd',function(){
callback.apply(this);
});
}
$this.css({
'-webkit-transform': 'translate3d(' + x + 'px,' + y + '%,0)'
});
return this;
}
CSS、非常にシンプル。適用される他のスタイルもありますが、それらは純粋に視覚的なものです。
#content.animate {
-webkit-transition: -webkit-transform .3s cubic-bezier(.16,0,0,1);
}
長い投稿で申し訳ありませんが、これは私をたくさん悩ませてきました!問題を分類できない場合は、それを取り除かなければならない時点です。
誰かがこれを以前に見たことがあり、助けてくれることを願っています。(または、上記のコードで明らかに明らかなエラーを確認できます!)
ありがとう、
意思 :)