モバイルブラウザがキーボードを表示すると、入力がまだ表示されるようにスクロールバーを移動しようとします。
IOS Safariでは、nearestスクロール親を見つけることにより、これを適切に行うようです。
AndroidネイティブまたはChromeモバイルブラウザでは、body要素を試してからあきらめているように見えるため、フォーカスされた入力はキーボードの下に隠れています。
セットする overflow-y: hidden
はbody要素にあります。スクロール可能なコンテナを作成し、そこにフォームを配置します。
画面の下部近くにある要素を選択すると、キーボードによって隠されます。
http://dominictobias.com/Android-scroll-bug/
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no"/>
<title>Android scroll/focus bug</title>
<style>
html, body {
margin: 0;
padding: 0;
height: 100%;
overflow: hidden;
}
.scroll {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
overflow-y: scroll;
}
input {
margin-bottom: 20px;
width: 100%;
}
</style>
</head>
<body>
<div class="scroll">
<input type="text" value="Input 1">
<input type="text" value="Input 2">
<input type="text" value="Input 3">
<input type="text" value="Input 4">
<input type="text" value="Input 5">
<input type="text" value="Input 6">
<input type="text" value="Input 7">
<input type="text" value="Input 8">
<input type="text" value="Input 9">
<input type="text" value="Input 10">
<input type="text" value="Input 11">
<input type="text" value="Input 12">
<input type="text" value="Input 13">
<input type="text" value="Input 14">
<input type="text" value="Input 15">
<input type="text" value="Input 16">
<input type="text" value="Input 17">
<input type="text" value="Input 18">
<input type="text" value="Input 19">
<input type="text" value="Input 20">
</div>
</body>
</html>
これを修正する方法はありますか?ブラウザの検出と厄介なハックが必要ですか?
これは、Android=ネイティブブラウザのバグです。ちなみに、ソフトキーボードで文字を入力すると、入力がビューにスクロールされます。
ページのどこかに配置された次のコードスニペットが役立つはずです。
if(/Android 4\.[0-3]/.test(navigator.appVersion)){
window.addEventListener("resize", function(){
if(document.activeElement.tagName=="INPUT"){
window.setTimeout(function(){
document.activeElement.scrollIntoViewIfNeeded();
},0);
}
})
}
Sergeからの回答はすばらしいですが、いくつかの変更を加えて改善しました。
この問題はAndroid 6でも発生しました。チェックのために追加しました。テキストエリアと入力の両方で機能するように修正する必要がありました。
if(/Android [4-6]/.test(navigator.appVersion)) {
window.addEventListener("resize", function() {
if(document.activeElement.tagName=="INPUT" || document.activeElement.tagName=="TEXTAREA") {
window.setTimeout(function() {
document.activeElement.scrollIntoViewIfNeeded();
},0);
}
})
}
Angular 1の修正が必要な場合は、ここで私が使用しました。
angular.module('<module name>').run(function ($window, $timeout) {
if(/Android [4-6]/.test($window.navigator.appVersion)){
$window.addEventListener("resize", function(){
if(document.activeElement.tagName=="INPUT" || document.activeElement.tagName=="TEXTAREA"){
$timeout(function() {
document.activeElement.scrollIntoViewIfNeeded();
});
}
});
}
});
少し時間を節約できる場合は、わずかな修正を提供します。
MDNは.scrollIntoViewIfNeeded
ブラウザの非互換性のbc => .scrollIntoView
は、ブラウザ互換性がわずかに高い、実行可能な代替物です。
if(/Android/.test(navigator.appVersion)) {
window.addEventListener("resize", function() {
if(document.activeElement.tagName=="INPUT" || document.activeElement.tagName=="TEXTAREA") {
document.activeElement.scrollIntoView();
}
})
}
これを少し異なって見ると、バグはブラウザの提案機能が原因であるようです。とにかく私が使用した提案は本当に欲しくないので:
if(/Android/.test(navigator.appVersion)){
$('input[type="text"]').attr('autocomplete', "off");
}
よりスムーズなエクスペリエンスを提供します。