javascript/html5の履歴オブジェクトとiframeに問題があります。私は自分の問題を説明する簡単なプロジェクトを書きました:
iframeと次へボタンのあるページです。[次へ]をクリックするたびに、増分カウンターを含む新しいページが読み込まれます。ただし、ブラウザの戻るボタンをクリックしても、私が望んでいることはできません。この投稿を次のセクションに分けて、問題を説明しましょう。
- 達成したいこと
- 現在のプロジェクトでの望ましくない結果
- すべてのコードを投稿する
1.達成したいこと
ユーザーに次のことをしてもらいたい:
- 新しいウィンドウを開き、http://dktest.evermight.com/にアクセスします
- 次のページをクリックして、レッドボックスがフェードインし、URL
http://dktest.evermight.com/count.html?count=0
がiframeとブラウザのアドレスバーの両方に表示されることを確認します - 次のページをもう一度クリック
http://dktest.evermight.com/count.html?count=1
して、iframeとブラウザのアドレスバーを確認してください - ブラウザの戻るボタンを1回クリックして、 iframe
http://dktest.evermight.com/count.html?count=0
とブラウザのアドレスバーの両方を確認します - ブラウザの戻るボタンを1回クリックして、ブラウザのアドレスバーを確認
http://dktest.evermight.com/
し、赤いボックスがフェードアウトするのを確認します。
2.現在のプロジェクトでの望ましくない結果
http://dktest.evermight.com/にある私のコードでは、現在、手順4と手順5が正しく実行されていません。手順4を実行すると、iframeは表示されますhttp://dktest.evermight.com/count.html?count=0
が、ブラウザのアドレスバーにが表示されますhttp://dktest.evermight.com/count.html?count=1
。ブラウザのアドレスバーを表示するには、ブラウザの戻るボタンをもう一度押す必要がありますhttp://dktest.evermight.com/count.html?count=0
。手順5を実行すると、赤いボックスがフェードアウトします。これはすばらしいことですが、アドレスバーはまだ表示されていhttp://dktest.evermight.com/count.html?count=0
ます。アドレスバーを表示するには、もう一度押す必要がありますhttp://dktest.evermight.com/
。
3.すべてのコードを投稿します
私のコードは非常に単純です。ソースはhttp://dktest.evermight.com/で表示できます。便宜上、ここにも投稿します。
index.html
<!DOCTYPE html>
<html>
<head>
<title></title>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
<script type="text/javascript">
var count=0;
function clicknext()
{
$('#container').fadeIn();
$('#iframe').attr('src','count.html?count='+count.toString());
$('html title').html(count);
history.pushState({blahblah:'whatgoeshere?'},'i dont know what goes here either','http://dktest.evermight.com/count.html?count='+count);
count++;
}
function hideContainer()
{
$('#container').fadeOut();
var closeurl = 'close.html';
if($('#iframe').attr('src') != closeurl )
$('#iframe').attr('src', closeurl);
}
$(document).ready(function(){
hideContainer();
});
</script>
</head>
<body>
<div id="container" style="display:none; background:red;">
<!-- IMPORTANT
When DOM first created, the iframe.src MUST BE initialize.html
I have some code that I need to fire on that page before the rest
of this document starts
-->
<iframe id="iframe" src="initialize.html"></iframe>
</div>
<input type="button" onclick="clicknext()"; value="next page" />
</body>
</html>
close.html
<!DOCTYPE html>
<html>
<script type="text/javascript">
parent.hideContainer();
</script>
</html>
count.html
count.htmlの内容を変更できません。私の実際のプロジェクトでは、count.htmlは実際にはYouTubeビデオであり、直接アクセスできないサーバー上にあります。
<html>
<body>Youtube video at url <script type="text/javascript">document.write(location.href);</script></body>
</html>
initialize.html
Perform application specific functionality
セクション1で説明したように、誰かが私のコードを修正して、ステップ4とステップ5の結果を達成できますか?
更新 わかりました、私が行っているいくつかの実験に基づいて、問題をもう少し理解しています。
実験1:行を変更してみました:
$('#iframe').attr('src','count.html?count='+count.toString());
に
$('#iframe')[0].contentWindow.location.replace('count.html?count='+count.toString());
これにより、手順4を正しく実行できました。どうやら、contentWindow.location.replace()は履歴オブジェクトにエントリを作成しません。ただし、これにより、実際にはyoutube/vimeoコンテンツのページであるcount.htmlのコンテンツに関連する他の問題が発生しました。youtube / vimeoコンテンツでは、.contentWindow.location.replace()ではなくattr('src')アプローチを介して情報をロードする必要があります。したがって、おそらく解決策は、attr('src')が履歴オブジェクトを使用してエントリを作成しないようにする方法を見つけることですか?
実験2私が試したもう1つの可能な解決策は、attr('src')およびhistory.pushState()呼び出しの順序を変更することでした。最初にattr('src')を呼び出し、次にhistory.pushState()を呼び出し、次にhistory.pushState()を最初に呼び出し、次にattr('src')を呼び出してみました。ただし、どちらの場合も、ブラウザの戻るボタンを押すと、最初に戻るのはiframeコンテンツです。したがって、履歴オブジェクト内の情報は一連のイベントの最後に利用可能であるため、履歴オブジェクトを介して自分自身にメッセージを渡して「ダブルバック」を実行する方法はありません。
実験3History.jsも試してみました。上記の私の問題を解決するために何もしませんでした。私の知る限り、これは通常の履歴オブジェクトとまったく同じように機能しました。
誰か他に私が試すことができるものはありますか?または、上記の実験のいずれかに変更を提案しますか?別のスタックオーバーフローの質問として、実験1をさらに詳しく見ていきます。