Wir können verwenden window.location.replace
zu vermeiden , Geschichte und Ziel auf Seite Anker ohne Seite neu geladen, aber nicht in iframes?
Das Problem ist eine CSP-Verletzung (Content Security Policy), deren Status script-src 'unsafe-inline'
aktiviert sein muss. Außer ich habe keinen CSP definiert, und selbst wenn ich einen definiere und zulasse script-src 'unsafe-inline'
, gibt es immer noch den gleichen Verstoßfehler. Gleiches Ergebnis in ie11 / chrome / ff.
Iframe in derselben Domain (im selben Verzeichnis).
- Zielen Sie auf den Iframe in der Konsole und verwenden Sie ihn
window.location.replace('/samepage.html#onpage_anchor')
in der Konsole. - Es klappt. Es zielt auf den On-Page-Anker ab, ohne die Seite neu zu laden und ohne Verlauf.
- Setzen Sie den gleichen Code inline auf Ankerlinks und es funktioniert.
- Verwenden Sie denselben Code in einem externen Skript, und erhalten Sie den Fehler "csp-Verletzung". Dies funktioniert gut, wenn nicht in einem Iframe.
Ich versuchte , einen CSP zu schaffen , der Aktion zu ermöglichen, aber nicht einmal die meisten permissiven Inhalt Sicherheitsrichtlinien möglich würden es erlauben.
Bearbeiten: Also habe ich Beispiele für Plunker zusammengestellt, die mehrere Dateien zulassen, damit ich geeignete hrefs verwenden kann, die auf die übergeordneten / untergeordneten Seiten verweisen.
Hinweise zu den Plunker-Beispielen:
Das Problem wird in diesen Beispielen nicht reproduziert. Das Skript funktioniert auch im Iframe einwandfrei. Der gleiche Code funktioniert jedoch nicht auf meinem lokalen Server oder wenn ich ihn live auf einem VPS ausführe.
Ich vermute, dass die CSP-Verletzung beim Plunker nicht ausgelöst wird, weil der Plunker dem Browser Inhalte über eine Art Abstraktionsschicht präsentiert.
Wenn Sie zum ersten Mal auf die Akkordeon-Links im übergeordneten Element klicken, wird eine Aktualisierung durchgeführt. Dies liegt daran, dass die Art und Weise, wie die Seite anfänglich geladen wird, nicht auf index.html verweist. Nachfolgende Klicks funktionieren wie erwartet ohne erneutes Laden der Seite. Kein Problem im iframe, da es zunächst auf child.html verweist
Dies sind gute Beispiele, um den Code zu zeigen, ohne dass Änderungen erforderlich sind, damit er funktioniert (wie bei der Notwendigkeit, die hrefs zu ändern, damit sie in den unten genannten Stackoverflow-Snippets funktionieren). Es ist auch gut, da es zeigt, dass das Javascript so funktioniert, wie es sollte. Aber es zeigt nicht das eigentliche Problem. Sie müssen es weiterhin in Ihren Editor laden und auf einem lokalen Server oder einer Live-Hosting-Umgebung ausführen, um das eigentliche Problem zu erkennen.
Plunker-Beispiele
Mit Skript: Ohne Geschichte
Ohne Skript: Mit Geschichte
Vereinfachtes Codebeispiel
Einfaches Akkordeon mit einem Eintrag. Ausreichend, um das Problem zu reproduzieren.
Durch Klicken auf Öffnen / Schließen wird das Akkordeon erweitert / reduziert, kein JS erforderlich. Der JS sollte genau das Gleiche tun, aber ohne Geschichte. Funktioniert gut, aber nicht in einem Iframe.
Code-Snippet-Notizen:
Sie können das Snippet ausführen, um eine Vorstellung davon zu bekommen, was ich beschreibe, aber es zeigt das Problem nicht wirklich.
Das Snippet verhält sich nicht wie in einem echten Browser, das Javascript funktioniert nicht.
Das Snippet zeigt den Code an, sollte jedoch in einem Iframe ausgeführt werden, um das Problem zu erkennen. Führen Sie es außerhalb eines Iframes aus, um den Unterschied und die Funktionsweise zu sehen .
- Wegen , wie die Verbindungen arbeiten mit dem JS (die gesamte URL zu ersetzen) sie tatsächlich muss so sein und
href="https://stackoverflow.com/thispage.html#ac1"
nicht nur ,href="#ac1"
wie sie im Snippet angezeigt (kann die tatsächliche HTML - Seite im Snippet nicht Ziel). Wenn Sie dies in Ihrem Editor versuchen (bitte tun Sie dies), denken Sie daran, die Links in dieses Format zu ändern,this_document.html#anchor
damit sie immer noch dieselben Seitenanker sind, aber die page.html ist im Link enthalten.
Das Skript
$(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);
});
Dies ist sehr einfach:
1. Die Funktion acAnch nimmt das href
Attribut und legt es dort ab window.location.replace()
.
2. Achten Sie auf Klicks auf Anker im Akkordeon, um die acAnch-Funktion auszuführen.
Das Skript wird also nur ausgeführt window.location.replace('/this_same_page.html#on_page_anchor')
Wenn Sie das in die Konsole legen, funktioniert es, keine CSP-Verletzung. Das Ausführen über ein externes Skript funktioniert jedoch nicht.
Inline auf den Links funktioniert gut:
onclick="event.preventDefault();window.location.replace('/thispage.html#acc0');"
onclick="event.preventDefault();window.location.replace('/thispage.html#acc1');"
Das auf die jeweiligen Links zu setzen funktioniert perfekt , aber ich bevorzuge es wirklich , kein solches Inline-Skript zu verwenden. Es muss eine Möglichkeit geben, dies mit einem externen Skript zu tun .
Ich habe versucht, das Javascript auf dem übergeordneten Element anstatt im Iframe auszuführen (natürlich mit Änderungen, um die Links innerhalb des untergeordneten Elements auszuwählen). Gleiches CSP-Fehlerergebnis.
Warum mache ich das?
Nun, die Seite ist viel komplexer als das Beispiel. Anker in Iframes funktionieren einwandfrei, fügen jedoch den Verlauf hinzu. Wenn Sie den obigen Code ohne Javascript ausführen (oder nur das Snippet ausführen), das Akkordeon einige Male öffnen und schließen und die Zurück-Taste verwenden, werden die Öffnungs- / Schließzustände durchlaufen.
Ich hätte nichts gegen den Verlauf, aber wenn er sich in einem Iframe befindet, wenn Sie die übergeordnete Seite verlassen und dann darauf zurückkommen, ist der Verlauf im Iframe unterbrochen. Beim Zurückgehen werden die Akkordeonzustände nicht mehr durchlaufen, sondern der Iframe wird immer wieder neu geladen. Anfänglich verursachen die Anker keine Iframe-Neuladungen, sondern durchlaufen lediglich den Akkordeonstatusverlauf, der einwandfrei funktioniert, bis Sie die Seite verlassen und zurückkehren. Dann geht zurück nicht mehr durch die Akkordeonzustände, sondern nur durch einen Stapel identischer Iframe-Nachladungen. Es ist sehr benutzerunfreundliches Verhalten.
Ich muss location.replace nicht verwenden, wenn es eine andere Methode gibt, die funktioniert. Ich habe jedoch viele andere Ansätze ausprobiert und festgestellt, dass Methoden, die dasselbe Ergebnis erzielen können, im Allgemeinen zu demselben Fehler führen.
Das Ziel besteht einfach darin , die Ankerlinks auf der Seite ohne erneutes Laden und ohne Verlauf innerhalb eines Iframes zu aktivieren .
Das Inline-Skript funktioniert. Können wir es in einer externen .js-Datei zum Laufen bringen?
quelle
<a href="#ac0" class="ac-close">Close</a>
sollte funktionieren.Antworten:
Ja, Sie können iframe mit -window-location-replace als Referenz verwenden. Sie können diesen Referenzlink Javascript location.replace und iframe verwenden
quelle
Sie können CSS anstelle des HTML-Iframe-Tags verwenden, da das Iframe-Tag in HTML entfernt wird
quelle