请查看这个GithubPage,我尝试在其中重现我遇到的问题。
当您单击第一个按钮时,它将创建一个段落,将其附加到本地存储项并显示它。
当您点击第二个按钮时,它会先清除本地存储,然后重定向到另一个页面。
现在,如果您从第 2 页单击浏览器后退按钮,您将返回到 index.html,但段落仍然在那里。如果你检查本地存储,这些段落会被删除,正如它们应该的那样,但它们仍然显示,就像返回index.html时js脚本没有执行一样。
我在使用 chrome 和 Firefox 时遇到了这个问题,但 Edge 的行为符合我的预期(回到 index.html,没有显示任何段落)。当我在本地实时服务器上测试它时,即使使用 Chrome,一切也都按预期工作。但在 GitHub 页面上并不正确。 通过浏览器的后退按钮访问页面时,Js 脚本是否会再次运行? 我是这么认为的,但是有人可以解释一下这是怎么回事吗?谢谢。
这是脚本
const addPEle = document.querySelector(".addP");
const clearPEle = document.querySelector(".clearP");
const contentEle = document.querySelector(".content");
addPEle.addEventListener("click", () => {
const curContent = localStorage.getItem("content") || "";
localStorage.setItem("content", `${curContent}<p>This is a paragraph.</p>`);
displayContent();
});
clearPEle.addEventListener("click", () => {
localStorage.setItem("content", "");
location.href = "page2.html";
// displayContent();
});
function displayContent() {
contentEle.innerHTML = "";
const content = localStorage.getItem("content") || "There is no paragraph.";
contentEle.innerHTML = content;
console.log("from displayContent function");
console.log(`content: ${content}`);
console.log(`localStorage: ${localStorage.getItem("content")}`);
}
displayContent();
这是因为后退缓存会保留您的页面及其状态,并且在向后导航时不会刷新您的页面。
您可以使用 PageLifeCycle 事件来检查您的页面是否导航回来,并根据需要重新加载。请参阅演示 https://page-lifecycle.glitch.me/ 来自 https://github.com/GoogleChromeLabs/page-lifecycle
window.addEventListener('pageshow', (event) => {
if (event.persisted) {
// page was restored from the bfcach
// Do your reload or re-render page with data
}
});
我也使用了
pageshow
但添加了更多层 if
语句检查..
我们也遇到过类似的情况,但是这对我们来说似乎只是 Firefox 中的一个问题(也许 Chrome 更新已经解决了这个问题?)并且仅适用于商店网格产品列表,因此我们检查用户是否也在这些页面上.
无论如何,在我们的例子中,因为这个问题只影响 Firefox 用户,所以我使用了
navigator.userAgent.toLowerCase().includes('firefox')
,它将返回 true
或 false
因此,如果这是真的,即是 Firefox 用户访问,我将使用
sessionStorage
存储他们当前的 URL 作为 preVisitedPage
变量,每个新页面访问都会将该 currentURL
与我们存储的 var preVisitedPage 进行比较。
一旦我开始跟踪用户浏览历史记录的方向,出现的有趣的事情是,当这个问题确实发生时,根据控制台日志返回信息的方式,看起来好像用户根据控制台说刷新了值
0
用于返回历史方向(刷新),但预期控制台会给出 -1
的值(向后导航),即单击的值; (值 +1
表示向前导航)。
然后我们引用我们的语句来检查当前页面是否与上一个会话访问的页面不同。正确的刷新是当前页面和先前会话访问的页面将是相同的 URL。如果上一个会话访问的页面返回的 URL 值与当前页面的 URL 值不同,则表明我们发现了错误,此时我们会强制重新加载,这几乎是无缝发生的。
这是完整的 JavaScript 代码:
const createFirefoxBrowsingStoreGridDirtyFix = () => {
// Check if the browser is Firefox
const isFirefox = navigator.userAgent.toLowerCase().includes('firefox');
if (isFirefox) {
const currentUrl = window.location.href;
const preVisitedPage = sessionStorage.getItem('preVisitedPage');
// Function to set 'preVisitedPage' session variable to the current URL
const setpreVisitedPage = () => {
sessionStorage.setItem('preVisitedPage', currentUrl);
};
// Function to check if 'preVisitedPage' is equal to the current URL
const isPreVisitedPage = () => {
return currentUrl === preVisitedPage;
};
// Check if the URL contains 'store-grid'
if (location.href.includes('store-grid')) { // TODO apply to Store Grid pages only
function reorient() { // After travelling in the history stack
const positionLastShown = Number(sessionStorage.getItem('positionLastShown'));
let position = history.state; // Absolute position in stack
if (position === null) { // Meaning a new entry on the stack
position = positionLastShown + 1; // Top of stack
// Stamp the entry with its own position in the stack
history.replaceState( position, /*no title*/'' );
}
// Keep track of the last position shown
sessionStorage.setItem( 'positionLastShown', String(position) );
// Discover the direction of travel by comparing the two
const direction = Math.sign( position - positionLastShown );
// Backward (-1), reload (0) and forward (1)
if (direction === -1) {
// User went backwards through browsing
} else if (direction === 0) {
// User reloaded page (Sometimes in Firefox this is triggered with Back-button for unknown reason)
// Check if the current page is different from the visited page
if (!isPreVisitedPage()) {
window.location.reload();
}
} else if (direction === 1) {
// User went forward through browsing
} else {
// Unknown Navigation Direction
}
setpreVisitedPage();
}
addEventListener( 'pageshow', reorient );
addEventListener( 'popstate', reorient );
}
}
};
createFirefoxBrowsingStoreGridDirtyFix();
通过提取整个函数内的一些案例,使这些案例更具全局性/可重用性,这可能会进一步改进,这将使该函数在
createFirefoxBrowsingStoreGridDirtyFix
函数中包含更少的代码。