履歴window.location.replace
を回避し、ページをリロードせずにページ上のアンカーをターゲットにするために使用できますが、iframeではできませんか?
問題は、CSP(コンテンツセキュリティポリシー)違反、状態をscript-src 'unsafe-inline'
有効にする必要があります。CSPを定義していない場合を除いて、CSPを定義して許可しscript-src 'unsafe-inline'
ても、同じ違反エラーが発生します。ie11 / chrome / ffでも同じ結果になります。
同じドメイン(同じディレクトリ内)の iframe 。
- コンソールでiframeをターゲットにして、コンソールで使用
window.location.replace('/samepage.html#onpage_anchor')
します。 - できます。 これは、ページをリロードすることなく、履歴なしでページ上のアンカーをターゲットにします。
- 同じコードをアンカーリンクにインラインで配置すると機能します。
- 外部スクリプトで同じコードを使用すると、csp違反エラーが発生します。 これは、iframe内でなくても正常に機能します。
私は、CSPを作成しようとしたアクションを許可しますが、いなくても、最も寛容なコンテンツセキュリティポリシー可能性は、それを可能にします。
編集:複数のファイルを許可する例をプランカーにまとめて、親/子ページを参照する適切なhrefを使用できるようにします。
プランカーの例に関するメモ:
問題はこれらの例では再現されません。 スクリプトは、iframeでも完全に機能します。ただし、同じコードがローカルサーバーで機能しないか、VPSでライブ実行すると機能しません。
プランカーはある種の抽象化レイヤーを介してブラウザーにコンテンツを提示しているため、CSP違反はプランカーでトリガーされないのではないかと思います。
親のアコーディオンリンクを初めてクリックすると、更新されます。これは、ページが最初にロードされる方法がindex.htmlを参照しないためです。以降のクリックは、ページをリロードしなくても期待どおりに機能します。最初はchild.htmlを参照するため、iframeの問題ではありません
これらは、コードを機能させるために変更を必要とせずにコードを表示するのに適した例です(下記のStackoverflowスニペットで機能させるためにhrefを変更する必要がある場合など)。また、javascriptが正常に機能していることも示しています。しかし、それは実際の問題を示していません。実際の問題を確認するには、エディターにロードしてローカルサーバーまたはライブホスティング環境で実行する必要があります。
プランカーの例
簡略化されたコード例
1つのエントリを持つ単純なアコーディオン。問題を再現するのに十分です。
開く/閉じるをクリックすると、アコーディオンが展開/折りたたまれます。JSは必要ありません。JSはまったく同じことを行いますが、履歴はありません。正常に機能しますが、iframeでは機能しません。
コードスニペットのメモ:
スニペットを実行して、私が説明していることについてのアイデアを得ることができますが、実際には問題を示していません。
スニペットは実際のブラウザのように動作せず、JavaScriptは機能しません。
スニペットはコードを示していますが、問題を確認するにはiframeで実行する必要があります。iframeの外で実行して、違いとその動作を確認します。
- リンクがJSでどのように機能するか(URL全体を置き換える)のため、スニペットに表示されるのと同じようにリンクするのではなく、 実際にはこのようにする必要があります(スニペットの実際のHTMLページをターゲットにすることはできません)。あなたがあれば、あなたのエディタでこれを試してください(行ってください)、その後、することを忘れないでください、この形式へのリンクを変更し、彼らはまだあるので、同じページのアンカー、しかしpage.htmlがリンクに含まれています。
href="https://stackoverflow.com/thispage.html#ac1"
href="#ac1"
this_document.html#anchor
スクリプト
$(document).ready(function() {
// anchor links without history
$.acAnch = function(event) {
event.preventDefault();
var anchLnk = $(event.target);
var anchTrgt = anchLnk.attr('href');
window.location.replace(anchTrgt);
}
// listen for anchor clicks
$('.accordion').on('click', 'a', $.acAnch);
});
これは非常に単純です
。1. acAnch関数はhref
属性を受け取り、にドロップしwindow.location.replace()
ます。
2.アコーディオン内のアンカーのクリックをリッスンして、acAnch関数を実行します。
つまり、スクリプトが実行するのは window.location.replace('/this_same_page.html#on_page_anchor')
それをコンソールに入れても機能し、CSP違反はありません。ただし、外部スクリプトから実行しても機能しません。
リンクのインラインは正常に動作します:
onclick="event.preventDefault();window.location.replace('/thispage.html#acc0');"
onclick="event.preventDefault();window.location.replace('/thispage.html#acc1');"
それをそれぞれのリンクに置くことは完璧に機能しますが、私は本当にそのようなインラインスクリプトを使用したくないです。これを外部スクリプトで行う方法が必要です。
iframeではなく親でjavascriptを実行してみました(もちろん、子内のリンクを選択するように変更しました)。同じCSPエラー結果。
なぜこれを行うのですか?
さて、サイトは例よりもはるかに複雑です。iframeのアンカーは正常に機能しますが、履歴が追加されます。JavaScriptなしで上記のコードを実行する(またはスニペットを実行する)場合、アコーディオンを数回開いて閉じ、[戻る]ボタンを使用すると、開いている閉じる状態に戻ります。
履歴は気にしませんが、iframe内にある場合、親ページを離れて戻ったときに、iframeの履歴が壊れています。戻ると、アコーディオンの状態は戻りませんが、代わりにiframeをリロードし続けます。最初、アンカーはiframeの再読み込みを引き起こしませんが、ページを離れて戻ってくるまで、アコーディオン状態の履歴を順を追って処理します。これは正常に機能します。その後、アコーディオン状態を経由せず、同一のiframeリロードの山を経由するだけです。非常にユーザーに不便な行動です。
機能する別のメソッドがある場合、location.replaceを使用する必要はありません。しかし、他の多くのアプローチを試してみましたが、同じ結果を達成できる方法では、一般的に同じエラーが発生することがわかりました。
目標は、iframe内でリロードせずに、履歴なしで、ページ上のアンカーリンク をアクティブにすることです。
インラインスクリプトが機能します。外部の.jsファイルで機能させることはできますか?
<a href="#ac0" class="ac-close">Close</a>
はずです。