2012-09-18 11 views
6

ページのスクロールを防ぐために、ドキュメントのtouchstartでpreventDefault()を使用します。残念ながら、これはあまりにも多くを防止します。ユーザーはもはや入力にフォーカスを合わせることができなくなります(ソフトキーボードを開く)。 jQueryのfocus()を使用して、タッチスタートの入力にフォーカスを当てることができます。これは、iOS(ほとんどの場合)ではソフトキーボードを開きますが、Androidでは決して使用しません。入力フォーカスを妨げずにモバイルブラウザでのスクロールを防止する

背景

は、私はできるだけモバイルアプリのようにしたいWebページを持っています。私はAndroidとiOSにのみ関心がありますが、フォームファクターはどれも重要です。私は、ページ内のコンテンツを画面サイズとまったく同じサイズにすることから始めます。これはユーザーが指をページに置くまでうまくいく。私はユーザーのスクロールを防ぐ必要があります。次のコードは、これを実現しますが、2つのオペレーティングシステムでは若干異なる方法で行います。 iOSの上で

$(document).on('touchstart', function(e) { 
    e.preventDefault(); 
}); 

、これは弾性スクロール防止:ユーザーがページをオフにスクロールしようとすることにより、Webページの後ろにテクスチャを明らかにすることができます。この機能は通常のWebページにはいいですが、私の場合はUXからの影響がありません。

Androidでは、アドレスバーを非表示にする便利なハッキングの啓示を防止します。 Androidブラウザはアドレスバーが表示された状態から開始しますが、ユーザーがページを下にスクロールすると消えます。プログラムで強制的にブラウザにアドレスバーを非表示にするには、loadで呼び出された関数にこのコード行を追加するだけです。

$('html, body').scrollTop(1); 

これはハック(だけでなく、唯一の)私たちがスクロールしなかった、とアドレスバーがもはや必要ではAndroidのブラウザを伝えるための方法です。

ドキュメントのpreventDefaultがないと、Androidブラウザでスクロールが許可され、アドレスバーが表示されます。

したがって、両方のOSには、ドキュメント上のすべてのタッチスタートでこのpreventDefault()を呼び出すのが良い理由がありますが、あまりにも多くのことを防ぎます。入力フィールドをタップすると何も行われません。 jQuery focus()の呼び出しを使うと、AndroidではなくiOS上のソフトキーボードだけが開くようになります。

$('input').on('touchstart', function() { 
    $(this).focus(); 
}); 

どのように私は、スクロールからページを防ぐが、入力フィールドにフォーカスを与えるために、ブラウザのネイティブ機能を使用することができますか?

注: このコード

$(document).on('touchstart', function(e) { 
    if (e.target.nodeName !== 'INPUT') { 
     e.preventDefault(); 
    } 
}); 

ユーザーはまだ限り、初期タッチが入力フィールド内に由来するように、ページをスクロールすることができますので、欠陥があります。

答えて

8

私は実際に別のプロジェクトでこの問題を解決し、忘れてしまいました。そして、これをタイピングすることでほとんどの方法を思い出しました。

キーはtouchmoveでやるだけです。

$(document).on('touchmove', function(e) { 
    e.preventDefault(); 
}); 

しかし、touchstart上でpreventDefaultは、ジェスチャ有効スライドショーのメニュー保存画像を防止することのような素敵なあらゆる種類のものを行います。私のプロジェクトにはこれも含まれています。

$(document).on('touchstart', function(e) { 
    if (e.target.nodeName !== 'INPUT') { 
     e.preventDefault(); 
    } 
}); 

誰かが追加コンテンツの提案や、これを再フォーマットしてより大きな視聴者に届くようにする方法があります。私はここのコンテンツを一箇所で見たことがないので、そうする必要があると感じました。

0

2つを組み合わせてください!

// prevent scrolling from outside of input field 
$(document).on('touchstart', function(e) { 
    if (e.target.nodeName !== 'INPUT') { 
     e.preventDefault(); 
    } 
}); 

// prevent scrolling from within input field 
$(document).on('touchmove', function(e) { 
    if (e.target.nodeName == 'INPUT') { 
     e.preventDefault(); 
    } 
}); 

これはおそらくどちらか完璧ではない、と私は最初の関数は、以下のリンクを防ぐことができますが、私は大規模なテストを行うために他の人にそれを残すだろうと、特に心配しています。

0

あなたの質問に対する簡単な答えは、代わりに "preventDefault"を使用しないで、ポインタイベントcssプロパティを使用して、スクロールする要素のスクロールを無効にします。ご入力の

CSS:

input { 
    pointer-events: auto !important; 
} 

touchstartイベントリスナー:

document.body.addEventListener('touchstart', function(e) { 
    if (e.target.nodeName === 'INPUT') { 
     this.style.pointerEvents = 'none'; 
    } 
}); 

あなたが入力をぼかすとき、ポインタ・イベントをリセットする必要があります。

document.body.pointerEvents = 'auto'; 

1良い質問

+0

ですから、各touchstartに、各touchendにDOMを変更しています。私たちがパフォーマンスを考えれば、これは軽い方法ではないかもしれません。 –

関連する問題