如何检测用户是否使用后退button进入页面?
当用户点击浏览器上的button时,这个问题类似于跟踪 ,但不一样…我有一个解决scheme,并张贴在这里供参考和反馈。 如果任何人有更好的select,我都耳朵!
情况是,我有一个“就地编辑”,la flickr页面。 即有一个“点击这里添加一个描述”的DIV,当点击变成一个带有保存和取消button的TEXTAREA。 单击“保存”将数据发布到服务器以更新数据库,并将新的描述放在DIV中代替TEXTAREA。 如果页面被刷新,则新的描述从数据库中以“点击编辑”选项显示。 这些日子相当标准的Web 2.0的东西。
问题是,如果:
- 该页面加载没有描述
- 用户添加说明
- 通过点击一个链接导航页面
- 用户点击后退button
然后显示(从浏览器的caching)是没有dynamic修改的DIV包含新的描述页面的版本。
这是一个相当大的问题,因为用户认为他们的更新已经丢失,并不一定明白他们需要刷新页面才能看到更改。
所以,问题是:如何将页面标记为在加载后进行修改,然后检测用户何时“回到”并在该情况下强制刷新?
使用隐藏的表单。 当您重新加载或按下返回button返回到页面时,表单数据将保留(通常)在浏览器中。 以下内容会进入您的页面(可能接近底部):
<form name="ignore_me"> <input type="hidden" id="page_is_dirty" name="page_is_dirty" value="0" /> </form>
在您的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'; }
嗅探表单的js必须在html完全parsing后执行,但如果用户延迟是一个严重问题,则可以将表单和js内联在页面的顶部(js秒)。
这篇文章解释它。 请参阅下面的代码: 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>
这个老问题是一个非常简单的现代解决scheme。
if (window.performance && window.performance.navigation.type == window.performance.navigation.TYPE_BACK_FORWARD) { alert('Got here using the browser "Back" or "Forward" button.'); }
目前所有主stream浏览器均支持window.performance。
如上所述,我find了一个解决scheme,并在这里发布供参考和反馈。
解决scheme的第一步是在页面中添加以下内容:
<!-- 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>
fresh.html
的内容并不重要,所以以下就足够了:
<!-- fresh.html --> <HTML><BODY></BODY></HTML>
当客户端代码更新页面时,需要将修改标记为:
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"; }
stale.html
完成所有的工作:当它被加载的时候,它会调用reload_stale_page
函数,如果需要的话刷新页面。 第一次加载(即修改后, reload_stale_page
函数将不会执行任何操作)。
<!-- stale.html --> <HTML><BODY> <SCRIPT type="text/javascript">window.parent.reload_stale_page();</SCRIPT> </BODY></HTML>
从我现阶段(最低限度)的testing来看,这似乎是按照要求工作的。 我忽略了什么?
您可以使用localStorage或sessionStorage( http://www.w3schools.com/html/html5_webstorage.asp )来设置一个标志(而不是使用隐藏的表单)。
你可以使用onbeforeunload事件解决它:
window.onbeforeunload = function () { }
使用这个页面,特别是通过@sajith关于@Nick White和这个页面的回答: http ://www.mrc-productivity.com/techblog/?p=1235
<form name="ignore_me" style="display:none"> <input type="text" id="reloadValue" name="reloadValue" value="" /> </form> $(function () { var date = new Date(); var time = date.getTime(); if ($("#reloadValue").val().length === 0) { $("#reloadValue").val(time); } else { $("#reloadValue").val(""); window.location.reload(); } });
我今天遇到类似的问题,我用localStorage(这里有一些jQuery)解决了它:
$(function() { if ($('#page1').length) { // this code must only run on page 1 var checkSteps = function () { if (localStorage.getItem('steps') == 'step2') { // if we are here, we know that: // 1. the user is on page 1 // 2. he has been on page 2 // 3. this function is running, which means the user has submitted the form // 4. but steps == step2, which is impossible if the user has *just* submitted the form // therefore we know that he has come back, probably using the back button of his browser alert('oh hey, welcome back!'); } else { setTimeout(checkSteps, 100); } }; $('#form').on('submit', function (e) { e.preventDefault(); localStorage.setItem('steps', 'step1'); // if "step1", then we know the user has submitted the form checkOrderSteps(); // ... then do what you need to submit the form and load page 2 }); } if ($('#page2').length) { // this code must only run on page 2 localStorage.setItem('steps', 'step2'); } });
Si基本上:
在第1页上,当用户提交表单时,我们在localStorage中设置一个值“steps”来指示用户采取的步骤。 同时,我们启动一个超时的函数来检查这个值是否已经改变(例如10次/秒)。
在第2页,我们立即改变所述值。
因此,如果用户使用后退button,并且浏览器以确切的状态恢复第1页,那么当我们离开它时,checkStepsfunction仍在运行,并且能够检测到localStorage中的值已被更改(并且可以采取适当的措施)。 一旦这个检查已经完成了它的目的,就没有必要继续运行了,所以我们不再使用setTimeout了。
这是一个jQuery版本。 由于Safari桌面/移动设备在用户按下后退button时处理caching的方式,因此我需要使用它几次。
$(window).bind("pageshow", function(event) { if (event.originalEvent.persisted) { // Loading from cache } });