如何使用后退按钮检测用户是否已访问某个页面?

Tom*_*Tom 86 browser ajax back-button

这个问题类似于用户在浏览器上点击按钮时的跟踪,但不一样......我有一个解决方案,并将其发布在此处以供参考和反馈.如果有人有更好的选择,我全都耳朵!

情况是我有一个"就地编辑"的页面,一个la flickr.即有一个"点击这里添加描述"DIV,点击时变成带有保存和取消按钮的TEXTAREA.单击"保存"将数据发布到服务器以更新数据库,并将新描述放在DIV中以代替TEXTAREA.如果刷新页面,则会使用"单击以编辑"选项从数据库中显示新描述.这些天相当标准的Web 2.0.

问题是,如果:

  1. 页面加载时没有描述
  2. 用户添加了描述
  3. 通过单击链接导航页面
  4. 用户单击后退按钮

然后显示的内容(来自浏览器的缓存)是没有包含新描述的动态修改的DIV的页面版本.

这是一个相当大的问题,因为用户认为他们的更新已丢失,并且不一定了解他们需要刷新页面才能看到更改.

因此,问题是:如何将页面标记为在加载后进行修改,然后检测用户何时"返回"并在该情况下强制刷新?

Nic*_*ite 77

使用隐藏的表格.当您重新加载或点击后退按钮返回页面时,表单数据(通常)会保留在浏览器中.以下内容位于您的页面中(可能位于底部附近):

<form name="ignore_me">
    <input type="hidden" id="page_is_dirty" name="page_is_dirty" value="0" />
</form>
Run Code Online (Sandbox Code Playgroud)

在您的JavaScript中,您需要以下内容:

var dirty_bit = document.getElementById('page_is_dirty');
if (dirty_bit.value == '1') window.location.reload();
function mark_page_dirty() {
    dirty_bit.value = '1';
}
Run Code Online (Sandbox Code Playgroud)

在完全解析html之后,必须执行嗅探表单的js,但如果用户延迟是一个严重问题,您可以将表单和js内联在页面顶部(js秒).

  • 在某些浏览器中,不会保留隐藏的标记.因此,您可以使用隐藏文本标记而不是使用隐藏的输入标记.<input type ="text"value ="0"id ='txt'name ='txt'style ="display:none"/> (10认同)
  • "表单数据在浏览器中保留(通常)" - 你能扩展它吗?是不是在某些浏览器中保留了?还是在某些情况下? (5认同)
  • 实际上,让我列出所有我认为出错的方法.(1)Opera保持页面的完整状态,不会重新执行js.(2)如果调整了缓存设置以强制页面从后台按钮上的服务器加载,则表单数据可能会丢失,这对于此问题的目的是正常的.(3)手机浏览器的缓存要小得多,浏览器可能已经从缓存中删除了页面(这不是出于问题). (4认同)
  • 这对我很有用.我确信它有崩溃的情况,但每个解决方案都会解决这个问题. (2认同)

Bas*_*sem 46

对于这个老问题,这是一个非常简单的现代解决方案.

if (window.performance && window.performance.navigation.type == window.performance.navigation.TYPE_BACK_FORWARD) {
    alert('Got here using the browser "Back" or "Forward" button.');
}
Run Code Online (Sandbox Code Playgroud)

window.performance目前支持所有主流浏览器.

  • `window.performance.navigation.TYPE_BACK_FORWARD`是一个常量,总是等于2.所以它只是用于比较. (5认同)
  • 看起来 `performance.navigation` 已被弃用,建议改用 https://developer.mozilla.org/en-US/docs/Web/API/PerformanceNavigationTiming/type (4认同)
  • 这将使您的脚本在 Safari 上崩溃 - 无论是 Mac 还是移动设备 (3认同)

Dre*_*ker 13

这篇文章解释了它.请参阅以下代码:http: //www.webkit.org/blog/516/webkit-page-cache-ii-the-unload-event/

<html>
    <head>
        <script>

            function pageShown(evt){
                if (evt.persisted) {
                    alert("pageshow event handler called.  The page was just restored from the Page Cache (eg. From the Back button.");
                } else {
                    alert("pageshow event handler called for the initial load.  This is the same as the load event.");
                }
            }

            function pageHidden(evt){
                if (evt.persisted) {
                    alert("pagehide event handler called.  The page was suspended and placed into the Page Cache.");
                } else {
                    alert("pagehide event handler called for page destruction.  This is the same as the unload event.");
                }
            }

            window.addEventListener("pageshow", pageShown, false);
            window.addEventListener("pagehide", pageHidden, false);

        </script>
    </head>
    <body>
        <a href="http://www.webkit.org/">Click for WebKit</a>
    </body>
</html>
Run Code Online (Sandbox Code Playgroud)


小智 5

您可以使用onbeforeunload事件解决它:

window.onbeforeunload = function () { }
Run Code Online (Sandbox Code Playgroud)

拥有onbeforeunload空事件管理器功能意味着每次访问页面时都会重新构建页面。Javascript 将重新运行,服务器端脚本将重新运行,页面将被构建,就像用户第一次点击它一样,即使用户只是通过点击后退或前进按钮进入页面.

这是一个示例的完整代码:

<html>
<head>
<title>onbeforeunload.html</title>
<script>
window.onbeforeunload = function () { }

function myfun()
{
   alert("The page has been refreshed.");
}
</script>

<body onload="myfun()">

Hello World!<br>

</body>
</html>
Run Code Online (Sandbox Code Playgroud)

试试看,离开此页面,然后使用浏览器中的“后退”或“前进”按钮返回。

它在 IE、FF 和 Chrome 中运行良好。

当然,您可以在myfun函数中做任何您想做的事情。

更多信息:http : //www.hunlock.com/blogs/Mastering_The_Back_Button_With_Javascript


get*_*up8 5

对于现代浏览器,现在这似乎是正确的方法:

const perfEntries = performance.getEntriesByType('navigation');
if (perfEntries.length && perfEntries[0].type === 'back_forward') {
  console.log('User got here from Back or Forward button.');
}
Run Code Online (Sandbox Code Playgroud)

截至 2020 年 1 月,这仍然是“实验性”,但似乎得到了很好的支持。

https://developer.mozilla.org/en-US/docs/Web/API/PerformanceNavigationTiming


Tom*_*Tom 2

如上所述,我已经找到了解决方案,并将其发布在这里以供参考和反馈。

解决方案的第一阶段是将以下内容添加到页面中:

<!-- at the top of the content page -->
<IFRAME id="page_is_fresh" src="fresh.html" style="display:none;"></IFRAME>
<SCRIPT style="text/javascript">
  function reload_stale_page() { location.reload(); }
</SCRIPT>
Run Code Online (Sandbox Code Playgroud)

的内容fresh.html并不重要,因此以下内容就足够了:

<!-- fresh.html -->
<HTML><BODY></BODY></HTML>
Run Code Online (Sandbox Code Playgroud)

当客户端代码更新页面时,需要标记修改,如下所示:

function trigger_reload_if_user_clicks_back_button()
{
  // "dis-arm" the reload stale page function so it doesn't fire  
  // until the page is reloaded from the browser's cache
  window.reload_stale_page = function(){};

  // change the IFRAME to point to a page that will reload the 
  // page when it loads
  document.getElementById("page_is_fresh").src = "stale.html";
}
Run Code Online (Sandbox Code Playgroud)

stale.html完成所有工作:加载时,它将调用reload_stale_page必要时刷新页面的函数。第一次加载时(即修改后,该reload_stale_page函数不会执行任何操作。)

<!-- stale.html -->
<HTML><BODY>
<SCRIPT type="text/javascript">window.parent.reload_stale_page();</SCRIPT>
</BODY></HTML>
Run Code Online (Sandbox Code Playgroud)

从我现阶段的(最低限度)测试来看,这似乎按预期工作。我是不是忽略了什么?