Vâng, có 2 cách để thay đổi location.href
. Bạn có thể viết location.href = "y.html"
, thao tác tải lại trang hoặc có thể sử dụng API lịch sử không tải lại trang. Tôi đã thử nghiệm với cái đầu tiên rất nhiều gần đây.
Nếu bạn mở cửa sổ con và nắm bắt tải trang con từ cửa sổ mẹ, thì các trình duyệt khác nhau hoạt động rất khác nhau. Điểm chung duy nhất là họ loại bỏ tài liệu cũ và thêm một tài liệu mới, vì vậy, ví dụ thêm trình xử lý sự kiện sẵn sàng hoặc tải vào tài liệu cũ không có bất kỳ tác dụng nào. Hầu hết các trình duyệt cũng xóa các trình xử lý sự kiện khỏi đối tượng cửa sổ, ngoại lệ duy nhất là Firefox. Trong Chrome với Á hậu Karma và trong Firefox, bạn có thể chụp tài liệu mới trong Trạng thái sẵn sàng tải nếu bạn sử dụngunload + next tick
. Vì vậy, bạn có thể thêm ví dụ: một trình xử lý sự kiện tải hoặc một trình xử lý sự kiện readystatechange hoặc chỉ cần ghi nhật ký rằng trình duyệt đang tải một trang với một URI mới. Trong Chrome với kiểm tra thủ công (có thể cả GreaseMonkey) và trong Opera, PhantomJS, IE10, IE11, bạn không thể chụp tài liệu mới ở trạng thái tải. Trong các trình duyệt đó, unload + next tick
lệnh gọi lại chậm hơn vài trăm mili giây so với sự kiện tải của trang kích hoạt. Độ trễ thường là 100 đến 300 msec, nhưng opera simetime tạo ra độ trễ 750 msec cho lần đánh dấu tiếp theo, điều này thật đáng sợ. Vì vậy, nếu bạn muốn có một kết quả nhất quán trong tất cả các trình duyệt, thì bạn sẽ làm những gì bạn muốn sau sự kiện tải, nhưng không có gì đảm bảo rằng vị trí sẽ không bị ghi đè trước đó.
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";
Nếu bạn chỉ chạy tập lệnh của mình trong Firefox, thì bạn có thể sử dụng phiên bản đơn giản hóa và chụp tài liệu ở trạng thái tải, vì vậy, ví dụ: một tập lệnh trên trang đã tải không thể điều hướng đi trước khi bạn ghi thay đổi 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);
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";
Nếu chúng ta đang nói về các ứng dụng trang đơn thay đổi phần băm của URI hoặc sử dụng API lịch sử, thì bạn có thể sử dụng hashchange
các popstate
sự kiện và sự kiện của cửa sổ tương ứng. Những thứ đó có thể ghi lại ngay cả khi bạn di chuyển trong lịch sử tới lui cho đến khi bạn ở trên cùng một trang. Tài liệu không thay đổi bởi những điều đó và trang không thực sự được tải lại.