web-dev-qa-db-ja.com

scrollTopがプログラムで変更された後の固定位置ボタンのモバイルSafariバグ...?

私はちょうどウェブページを完成させましたが、Mobile Safari(iPhoneおよびiPad iOS 5.0.1)には1つのバグがあり、右上隅と右下隅に固定された2つのボタンがあります。

ボタンは、ページの残りの部分を開くテキストボックスで[送信]をクリックするまでフェードインしません...ページの残りの部分が読み込まれ、ボタンがフェードインした後、どちらかをクリックすると、両方が機能します...

ただし、それらをクリックするとプログラムによるスクロールが発生し、そのスクロールが完了した後、指でページを物理的にスクロールするまで、いずれかのボタンをクリックすることはできなくなります。

私が気づいたのは、プログラムスクロールの後、TOPボタンの少し下をタップすると、BOTTOMボタンをタップしているようにハイライトが表示され、下部ボタンのアクションが処理され、スクロールするとバグであることがわかりますプログラム的に固定位置ボタンはページの残りの部分とともに移動し、実際のタッチスクロールが実行されるまで固定位置に戻りません。

誰もこれを回避する方法を知っていますか?

どのボタンが押されたかを示すポップアップを追加したので、テストすることができます。最初に押したダウンボタン(動作する)をもう一度押してみてください。動作しませんが、アップボタンのすぐ下をクリックします。下ボタンのアクションが発生するのがわかります。

http://www.tsdexter.com/ceos

助けてくれてありがとう。

トーマス

(また、バグをAppleに送信することができる場所を示していただければ、既にお持ちでない限り、それでも良いでしょう)

編集:送信矢印のいずれかをクリックするだけで、デフォルトの賃金/給与を入力する必要はありません

編集2:同じ問題を示すより簡単な例です。

http://www.tsdexter.com/MobileSafariFixedPosBug.html

編集3:アップルに報告されたバグ

35
tsdexter

101%の高いdivを追加して(ほぼ)すぐに削除することで回避しました。

試してください:

<style>
.iosfix {
  height: 101%;
  overflow: hidden;
}
</style>

スクロールすると:

window.scrollTo(0, _NEW_SCROLLTOP_);
$('body').append($('<div></div>').addClass('iosfix'));
setTimeout(function() {
  $('.iosfix').remove();
}, 500);

JQuery.scrollToでも機能します。

例を参照してください here

13
Chad Smith

また、2つの異なるiPadアプリケーションでこのバグが発生しました。最適な修正方法は、アニメーションスクロールが終了したら固定要素から固定位置を一時的に削除し、アニメーションを実行した垂直値でwindow.scrollを使用することでした。までスクロールし、最後に位置固定スタイルを再適用します。 ipadが要素を再レンダリングするときに非常に小さなブリップを引き起こしますが、バグよりも望ましいです。

var $fixedElement = $('#fixedNavigation');
var topScrollTarget = 300;
$("html:not(:animated),body:not(:animated)").stop().animate({ scrollTop: topScrollTarget }, 500, "swing", function(evt) {
    $fixedElement.css({ "position": "relative" });
    window.scroll(0, topScrollTarget );
    $fixedElement.css({ "position": "fixed" });
});
28
Dominic Warren

個別の固定要素(モーダルポップアップ+固定ブラックアウトdiv +通常の固定ツールバー)に複数のリンクがあり、これらの回答はどれも機能していなかったため、同じテーマでバリエーションを試すことについていじくりました。これらすべてが示唆するように、キーは要素を再レンダリングすることです。

最初に、固定要素の幅に1pxを追加して削除しようとしました。これは再レンダリングを引き起こしましたが、再レンダリングされた要素は再レンダリングされていない要素と不整合になりました-このiOSバグの別の結果は私が疑っています。答えは、単にボディの幅に追加し、再度減算する(またはautoに設定する)ことでした。つまり:

//jQuery will calculate the current width and then +1 to this and set it
$('body').css('width', '+=1');

//Remove width css
setTimeout(function() {
  $('body').css('width', '');
}, 1);

Jqueryを使用しない場合、bodyの現在の幅+ 1pxを取得してから、幅を設定する必要があります。

7
Ed Kirk

私のような場合、以前の解決策のどれもあなたのために働いていないなら、ここに私の解決策があります。

トリックは次のとおりです。

  • スクロールしてください(AnimateまたはscrollToなど)
  • スクロールの直後に、position:absolute your fixed elements
  • 「touchmove」イベントで、position:fixedを復元します

次に例を示します。

  $('body').animate({
       scrollTop: newPos}, 1000, 'jswing', function () {
          $('header').css({position:'absolute', top:newPos});
  });

  $(document).bind('touchmove',function(){
       $('header').css({position:'fixed', top:'0px'});
  });   

スティッキーフッターやその他のフローティング固定要素にも同じトリックを使用しました。

4

このバリエーションも私にとってはうまくいきました。モバイル上でできる限りフレームワークを使用しないようにしています。

    var d = document.createElement("div");
    d.style.height = "101%";
    d.style.overflow = "hidden";
    document.body.appendChild(d);
    window.scrollTo(0, scrollToM);
    setTimeout(function() {
        d.parentNode.removeChild(d);
    }, 10);
3
httpete


これに数時間を費やした後、回避策を見つけました。スクロール(アニメーションあり)してから、同じポイント(アニメーションなし)に再度スクロールしてみてください。
この方法では、ブラウザに誤ったレンダリングをビューから強制的に削除させます。

例:

$('body, html')
    .animate({scrollTop: 0})
    .scrollTop(0);
2
Luca De Angelis

IOS5とJQueryMobileでも同じ問題が発生していました。ヘッダーとフッターを修正。拡張可能なコンテンツと突然、ゴーストフッターがありましたが、それは見ることはできますが、触ることはできませんでした。ポジションを絶対に変えてから仕事に戻るのに少し問題がありました。時々しか機能しないようでした。私はこれを使用することになりました。

        $(myFixedFooter).css("position", "relative").hide(0, function () {
            $(this).show(0).css("position", "");
        });

これは、フッターがその処理を行うときに、反抗的に「ブリップ」を作成します。しかし、フッターがページの下部に留まる時間の約98%が見つかりました。私が見つけて試した他のすべての回避策と調整は、常にフッターを下部に残していないか、そもそも問題を解決していませんでした。

うまくいけばAppleは間もなく修正されます。

1
JDubDev

サンプルコード

if (navigator.userAgent.match(/iPhone|iPad|iPod/i)) {
    $(document).on('focus', 'input, textarea', function() {
        $('header').css({'position':'static'});
    });
    $(document).on('blur', 'input, textarea', function() {
        $('header').css({'position':'fixed'});
    });
}
0
ShibinRagh

ソリューションのもう1つのバリエーションは、ドキュメントの幅のサイズを1px増やし、すぐに元に戻すことです。これには、これ以上要素を作成しないという利点があり、私が経験したちらつきはありません。

https://stackoverflow.com/a/11479118/43217

0
mckamey

誰かを助けることができる場合:

私はまったく同じ問題を抱えていて、私のコードは次のようなものでした(単一ページのWebアプリです)。

window.scrollTo(0,0);
$('section.current').removeClass('current');
$(target).addClass('current');

私はすべてを試して何時間も費やしました(101%の高さdiv、位置タイプを変更...)が、最終的に Device-Bugs で説明した最後の提案がその日を救いました。私の場合、divがレンダリングされていないときはスクロールするだけでした:

$('section.current').removeClass('current');
window.scrollTo(0,0);
$(target).addClass('current');
0
Romain

私が書いているiPhoneアプリであなたが説明する正確な振る舞いを発見しました。右側にインデックスがあるHTMLテキストをたくさんロードします。メニューから項目を選択してテキストをスクロールすると、メニューが応答しなくなります(ランディングゾーンがその下からスクロールアウトしたため)。また、テキストの小さなスクロールでもインデックスメニューが再び有効になることもわかりました。

テストケースを作成し、ここにファイルをアップロードしました(これをiPhone以外のブラウザーで表示する場合は、ウィンドウを垂直方向に小さくして、正しい動作を確認します)。

http://www.misterpeachy.com/index_test.html

BをタップしてからBをもう一度タップした後、インデックスメニューがテキストでスクロールしていることがわかりました(表示されているメニューは移動しませんでした)。 B(基本的には移動しない)にスクロールする代わりに、Dにスクロールしました。

今私は立ち往生しています。メニュー項目から指を離した後(およびテキストがスクロールした後に)テキストを1ピクセルスクロールするJavaScriptコード(JavaScriptでプログラミングしたことがないので、わずかな問題です)を追加できることを期待していますもちろん、選択した場所に)。 JavaScriptがスクロールを検出してから、別のスクロールを追加できる場合があります。

0
Cliff Harris