38

これを、「これまで誰も気付かなかったなんて信じられない」または「何かが欠けているに違いない」のいずれかのカテゴリに提出します。

iOS で単純な操作を行うwindow.history.pushStateと、ユーザーのジェスチャーに反応しない限り、ロケーション バーは更新されないようです。状態自体はプッシュされます (戻るボタンを押すとわかります)。

問題を再現するために思いついた最も小さなテストケースは次のとおりです。

http://thelink.is/history-api-ios-bug

History API をサポートするデスクトップ ブラウザでは、ロケーション バーの URL が 1 秒ごとに /0、/1 などに変わります。iOS では – iPhone (iOS 4.3 を実行) および iPad (iOS 4.3.3 を実行) でテスト済み – ロケーションバーは更新されませんが、戻るボタンを押すと正しい以前のロケーションに移動します (テストケースでは 404 になるため、これらの URL を処理するバックエンド ロジックはありません)。

考え?回避策?泣いて抱きしめる肩?

更新: この問題は iOS 5 で修正されました。

4

5 に答える 5

23

つまり、iOSは履歴APIの周りに独自のセキュリティを追加しました。つまり、スクリプトを使用してURLを変更することはできません。Aralの例のように、履歴APIがURL(つまり、クリック)を変更できるのはユーザーアクションのみです。

回避策は、URLにハッシュ(別名フラグメント識別子)を使用することです。

代わりにhistory.pushState、場所を変更します。

var i = 0;
var locationUpdateInterval = setInterval(function(){
  window.location.hash = i;
  i++;
}, 1000);   

iOSアプリでその場所が変更されたとき、またはアプリの特定のページ/パネルへのパーマリンクがある場合にイベントをキャプチャするには、次のようにします。

// named function on purpose for later
function hashchange() {
  var pageId = location.hash.substr(1); // drop the # symbol
  // do something with pageId
}

window.onhashchange = hashchange;

// onload - if there's a hash on the url, try to do something with it
if (location.hash) hashchange();

pushStateiOSで/を使用できないのはかなり貧弱ですがpopState、ユーザーがアクションを開始しない限りフルスクリーンビデオをトリガーできないのと同じセキュリティです。これは、iOSでビデオまたはオーディオコンテンツをダウンロードするのと同じです。スクリプトを作成する場合、ユーザーはそれを開始する必要があります(何らかの方法で)。

Androidについてのメモと同じように、問題は非常に似ているため、これはAndroidの回避策としても機能するはずです。

デスクトップのサポートが必要な場合、ほとんどのブラウザはサポートonhashchangeしますが、ご想像のとおり、IEは遅れをとっています-そのため、その悪い子をポリフィルすることができます(jQueryが必要です...): http: //benalman.com/projects/jquery- hashchange-plugin /

お役に立てば幸いです。

于 2011-05-29T14:05:21.287 に答える
3

https://github.com/browserstate/history.jsを使用すると問題なく動作します。これにより、HTML5 History API に関する他の多くのクロス ブラウザーのバグも修正されます。

v1.7 の時点で、解決されたバグは次のとおりです。

  • History.jsは、次のブラウザーのバグ を解決します。
    • HTML5 ブラウザ
      • Chrome 8 には、初期状態に戻るときに正しい状態データが含まれていないことがあります。
      • onhashchangeSafari 5、Safari iOS 4、および Firefox 3 と 4 は、ページがハッシュでロードされたときにイベントを発生させません
      • onpopstateSafari 5 および Safari iOS 4は、他のブラウザーとは異なり、ハッシュが変更されたときにイベントを発生させません。
      • replaceStateSafari 5 および Safari iOS 4 は、ハッシュが呼び出し /バグ レポートに置き換えられると、正しい状態に戻らない
      • Safari 5 および Safari iOS 4 がビジー状態で状態変更の適用に失敗することがある /バグ レポート
      • RC より前の Google Chrome 8、9、10 および Firefox 4onpopstateは、ページが読み込まれると常に起動します /推奨事項を変更します
      • Safari iOS 4.0、4.1、4.2 では HTML5 History API が動作していますが、ブラウザの実際の戻るボタンは機能しないため、HTML4 ブラウザとして扱います。
      • HTML5 ブラウザーのどれも、実際にはおよび呼び出しのtitle引数を使用しません。pushStatereplaceState
    • HTML4 ブラウザ
      • onhashchangeMSIE 6,7 や Firefox 2 などの古いブラウザにはイベントがありません
      • MSIE 6 および 7 は、指示された場合でもハッシュを適用しない場合があります (適用関数への 2 回目の呼び出しが必要です)。
      • Opera 以外の HTML4 ブラウザーでは、ハッシュが適用されない場合にハッシュが適用されないことがあります。urlencoded
    • すべてのブラウザ
      • サイトを離れてから戻ると、状態データとタイトルは保持されません (ページの更新を含む)。
      • 州のタイトルは決して適用されませんdocument.title
于 2011-05-29T14:57:19.380 に答える
1

(更新:レミーも答えたのを見ただけです。代わりに、上記の彼の詳細な答えを読んでください。)

Remyは、この問題の回避策をTwitterで提供しました。

基本的に、location.hashを変更すると、ロケーションバーのアドレスが更新されます。ただし、これにより、履歴に別のエントリが作成されます(これは、私が達成しようとしていることでは機能しません)。私が実装している回避策は、iOSのバグが修正されるまで、iOSにはハッシュバンURLを使用し、他のプラットフォームには通常のURLを使用することです。これは絶対に理想的ではなく、iOS上のモバイルSafariがデスクトップ上のChrome、Firefox、Safariのように動作し始めることを願っています。

于 2011-05-29T14:03:30.473 に答える
1

これが私が見つけたものです:

プッシュされた場所にハッシュ記号が含まれている場合、アドレスバーが更新されます。したがって、これは機能します:

window.history.pushState(data, title, 'a/new/url#');

ただし、window.location オブジェクトは更新されないため、プッシュされた URL を変数に保存し、プッシュされた場所が必要な場合は window.location の代わりにそれを使用する必要があります。

Android の Safari でテスト済み。

于 2011-08-16T14:01:47.567 に答える
0

ちょっとうまくいくハックを見つけました。history.pushState の直後にハッシュを変更すると、ロケーション バーが更新されることがわかりました。お気に入り:

        window.history.pushState(data, title, 'a/new/url');
        window.location.hash = 'new';

ロケーションバーをhttp://example.com/a/new/url#newに変更します。ハッシュが独自の履歴エントリになるため、別の問題が発生します。したがって、とにかく onHashChange をリッスンする必要があります。

少し複雑ですが、ハッシュバン URL が本当に嫌いで、それについて非常に声高に主張する人もいます。だからそれだけの価値があります。

于 2011-06-27T22:34:38.727 に答える