Nun, es gibt zwei Möglichkeiten, das zu ändern location.href
. Sie können entweder schreiben location.href = "y.html"
, wodurch die Seite neu geladen wird, oder Sie können die Verlaufs-API verwenden, die die Seite nicht neu lädt. Ich habe in letzter Zeit viel mit dem ersten experimentiert.
Wenn Sie ein untergeordnetes Fenster öffnen und die Last der untergeordneten Seite aus dem übergeordneten Fenster erfassen, verhalten sich verschiedene Browser sehr unterschiedlich. Das einzige, was häufig vorkommt, ist, dass das alte Dokument entfernt und ein neues hinzugefügt wird. Das Hinzufügen von Readystatechange- oder Load-Ereignishandlern zum alten Dokument hat also keine Auswirkungen. Die meisten Browser entfernen auch die Ereignishandler aus dem Fensterobjekt. Die einzige Ausnahme ist Firefox. In Chrome mit Karma Runner und in Firefox können Sie das neue Dokument im Ladebereitschaftsstatus erfassen, wenn Sie es verwendenunload + next tick
. So können Sie beispielsweise einen Ladeereignishandler oder einen Readystatechange-Ereignishandler hinzufügen oder einfach protokollieren, dass der Browser eine Seite mit einem neuen URI lädt. In Chrome mit manuellen Tests (wahrscheinlich auch GreaseMonkey) und in Opera, PhantomJS, IE10, IE11 können Sie das neue Dokument nicht im Ladezustand erfassen. In diesen Browsern unload + next tick
ruft der Rückruf einige hundert ms später auf, als das Ladeereignis der Seite ausgelöst wird. Die Verzögerung beträgt normalerweise 100 bis 300 ms, aber die Oper simetime macht eine Verzögerung von 750 ms für den nächsten Tick, was beängstigend ist. Wenn Sie also in allen Browsern ein konsistentes Ergebnis erzielen möchten, tun Sie nach dem Ladeereignis, was Sie möchten. Es gibt jedoch keine Garantie dafür, dass der Speicherort zuvor nicht überschrieben wird.
var uuid = "win." + Math.random();
var timeOrigin = new Date();
var win = window.open("about:blank", uuid, "menubar=yes,location=yes,resizable=yes,scrollbars=yes,status=yes");
var callBacks = [];
var uglyHax = function (){
var done = function (){
uglyHax();
callBacks.forEach(function (cb){
cb();
});
};
win.addEventListener("unload", function unloadListener(){
win.removeEventListener("unload", unloadListener);
setTimeout(function (){
win.document.readyState;
if (win.document.readyState === "complete")
done();
else
win.addEventListener("load", function (){
setTimeout(done, 0);
});
}, 0);
});
};
uglyHax();
callBacks.push(function (){
console.log("cb", win.location.href, win.document.readyState);
if (win.location.href !== "http://localhost:4444/y.html")
win.location.href = "http://localhost:4444/y.html";
else
console.log("done");
});
win.location.href = "http://localhost:4444/x.html";
Wenn Sie Ihr Skript nur in Firefox ausführen, können Sie eine vereinfachte Version verwenden und das Dokument in einem Ladezustand erfassen, sodass beispielsweise ein Skript auf der geladenen Seite nicht weg navigieren kann, bevor Sie die URI-Änderung protokollieren:
var uuid = "win." + Math.random();
var timeOrigin = new Date();
var win = window.open("about:blank", uuid, "menubar=yes,location=yes,resizable=yes,scrollbars=yes,status=yes");
var callBacks = [];
win.addEventListener("unload", function unloadListener(){
setTimeout(function (){
callBacks.forEach(function (cb){
cb();
});
}, 0);
});
callBacks.push(function (){
console.log("cb", win.location.href, win.document.readyState);
if (win.location.href !== "http://localhost:4444/y.html")
win.location.href = "http://localhost:4444/y.html";
else
console.log("done");
});
win.location.href = "http://localhost:4444/x.html";
Wenn es sich um Einzelseitenanwendungen handelt, die den Hash-Teil des URI ändern oder die Verlaufs-API verwenden, können Sie das hashchange
bzw. das popstate
Ereignis des Fensters verwenden. Diese können auch dann erfasst werden, wenn Sie sich im Verlauf vor und zurück bewegen, bis Sie auf derselben Seite bleiben. Das Dokument ändert sich dadurch nicht und die Seite wird nicht wirklich neu geladen.