Ну, есть 2 способа изменить location.href
.Либо вы можете написать location.href = "y.html"
, который перезагружает страницу, либо можете использовать API истории, который не перезагружает страницу.Недавно я много экспериментировал с первым.
Если вы открываете дочернее окно и фиксируете загрузку дочерней страницы из родительского окна, то разные браузеры ведут себя очень по-разному.Единственное, что является общим, это то, что они удаляют старый документ и добавляют новый, поэтому, например, добавление обработчиков событий readystatechange или load в старый документ не имеет никакого эффекта.Большинство браузеров также удаляют обработчики событий из объекта окна, единственным исключением является Firefox.В Chrome с Karma Runner и в Firefox вы можете захватить новый документ в загрузке readyState, если вы используете unload + next tick
.Таким образом, вы можете добавить, например, обработчик события загрузки или обработчик события readystatechange, или просто зарегистрировать, что браузер загружает страницу с новым URI.В Chrome с ручным тестированием (возможно, и в GreaseMonkey) и в Opera, PhantomJS, IE10, IE11 вы не можете захватить новый документ в состоянии загрузки.В этих браузерах unload + next tick
вызывает обратный вызов на несколько сотен мсек позже, чем событие загрузки страницы.Задержка, как правило, составляет от 100 до 300 мсек, но время оперы делает задержку 750 мсек для следующего такта, что пугает.Поэтому, если вы хотите получить стабильный результат во всех браузерах, то вы делаете то, что хотите после события загрузки, но нет гарантии, что местоположение не будет переопределено до этого.
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); // Firefox remembers, other browsers don't
setTimeout(function (){
// IE10, IE11, Opera, PhantomJS, Chrome has a complete new document at this point
// Chrome on Karma, Firefox has a loading new document at this point
win.document.readyState; // IE10 and IE11 sometimes fails if I don't access it twice, idk. how or why
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";
Если вы запускаете свой скрипт только в Firefox, вы можете использовать упрощенную версию и захватывать документ в состоянии загрузки, так что, например, скрипт на загруженной странице не может перемещаться до входа в систему.Изменение URI:
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);
// be aware that the page is in loading readyState,
// so if you rewrite the location here, the actual page will be never loaded, just the new one
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";
Если речь идет об одностраничных приложениях, которые изменяют хеш-часть URI или используют API истории, то вы можете использовать события hashchange
и popstate
окно соответственно.Они могут захватывать, даже если вы перемещаетесь в истории назад и вперед, пока не останетесь на той же странице.Документ не изменяется, и страница не перезагружается.