如何停止使用JavaScript的浏览器后退button

我在做在线测验应用程序。 我想限制用户,而回到考试中。 我已经试过下面的脚本,但它停止了我的计时器。 我该怎么做,请build议我。 我已经包含源代码。 计时器存储在cdtimer.js中

<script type="text/javascript"> window.history.forward(); function noBack() { window.history.forward(); } </script> <body onLoad="noBack();" onpageshow="if (event.persisted) noBack();" onUnload=""> 

我有考试计时器,需要从MySQL数据库的考试时间,并启动计时器,因此它停止时,我把代码禁用后退button。 会有什么问题。

为什么禁用后退button不能真正起作用有很多原因。 您最好的select是警告用户:

 window.onbeforeunload = function() { return "Your work will be lost."; }; 

此页面列出了许多可以尝试禁用后退button的方法,但不保证:

http://www.irt.org/script/311.htm

覆盖Web浏览器的默认行为通常是一个糟糕的主意。 由于安全原因,客户端脚本没有足够的权限来执行此操作。

有几个类似的问题也被问到,

  • 我怎样才能防止退格键导航回来?

  • 如何防止JavaScript的退格button的浏览器的默认历史logging的后退行动?

不能实际禁用浏览器后退button。 但是,您可以使用自己的逻辑来执行魔术操作,以防止用户导航回来,从而导致其被禁用。 这里是如何,看看下面的代码片段。

 (function (global) { if(typeof (global) === "undefined") { throw new Error("window is undefined"); } var _hash = "!"; var noBackPlease = function () { global.location.href += "#"; // making sure we have the fruit available for juice (^__^) global.setTimeout(function () { global.location.href += "!"; }, 50); }; global.onhashchange = function () { if (global.location.hash !== _hash) { global.location.hash = _hash; } }; global.onload = function () { noBackPlease(); // disables backspace on page except on input fields and textarea.. document.body.onkeydown = function (e) { var elm = e.target.nodeName.toLowerCase(); if (e.which === 8 && (elm !== 'input' && elm !== 'textarea')) { e.preventDefault(); } // stopping event bubbling up the DOM tree.. e.stopPropagation(); }; } })(window); 

这是在纯粹的JavaScript,所以它可以在大多数的浏览器。 它也将禁用退格键,但键将在input字段和textarea内正常工作。

推荐设置:

将此代码段放在单独的脚本中,并将其包含在您想要此行为的页面上。 在当前的设置中,它将执行DOM的onload事件,这是此代码的理想入口点。

工作DEMO!

在以下浏览器中进行testing和validation,

  • 铬。
  • Firefox浏览器。
  • IE浏览器(8-11)和边缘。
  • 苹果浏览器。
 <script> window.location.hash="no-back-button"; window.location.hash="Again-No-back-button";//again because google chrome don't insert first hash into history window.onhashchange=function(){window.location.hash="no-back-button";} </script> 

此代码将禁用支持HTML5 History API的现代浏览器的后退button。 在正常情况下,按下后退button可以返回到前一页。 如果使用history.pushState(),则开始向当前页面添加额外的子步骤。 它的工作方式是,如果您要使用history.pushState()三次,然后开始按下后退button,前三次将在这些子步骤中导航,然后第四次返回到上一页。

如果将此行为与popstate事件上的事件侦听器结合使用,则可以基本上设置子状态的无限循环。 所以,你加载页面,推入一个子状态,然后点击后退button,这会popup一个子状态,并且会推另一个,所以如果你再次按下后退button,它将永远不会用完子状态。 如果你觉得有必要禁用后退button,这会让你在那里。

 history.pushState(null, null, 'no-back-button'); window.addEventListener('popstate', function(event) { history.pushState(null, null, 'no-back-button'); }); 

我遇到了这个问题,需要一个解决scheme,在各种浏览器上正常工作, 包括Mobile Safari (发布时为iOS9)。 没有一个解决scheme是完全正确的。 我提供以下(在IE11,FireFox,Chrome和Safari上testing):

 history.pushState(null, document.title, location.href); window.addEventListener('popstate', function (event) { history.pushState(null, document.title, location.href); }); 

请注意以下几点:

  • history.forward() (我的旧解决scheme)不能在移动Safari上工作 – 它似乎什么都不做(即用户仍然可以回去)。 history.pushState()在所有这些工作。
  • history.pushState()的第三个参数是一个url 。 传递类似'no-back-button''pagename'的string的解决scheme似乎工作正常,直到您尝试页面上的刷新/重新载入,此时浏览器尝试生成“页面未find”错误find一个网页作为它的url。 (浏览器也可能在页面上包含该string,这是丑陋的。) location.href应该用于Url。
  • history.pushState()的第二个参数是一个标题 。 环顾networking大多数地方说这是“不使用”,所有的解决scheme在这里传递null 。 但是,至less在移动Safari中,将页面的Url放入用户可以访问的历史logging下拉列表中。 但是,当正常添加页面访问的条目时,它会放入其标题 ,这是可取的。 所以传递document.title的结果是相同的行为。

这是我能做到的。 怪异地改变window.location在铬和safari中没有工作得很好。 会发生这样的情况:location.hash不会在chrome和safari的历史logging中创build一个条目。 所以你将不得不使用pushstate。 这在所有浏览器中都适用于我。

  history.pushState({ page: 1 }, "title 1", "#nbb"); window.onhashchange = function (event) { window.location.hash = "nbb"; }; 
 <html> <head> <title>Disable Back Button in Browser - Online Demo</title> <style type="text/css"> body, input { font-family: Calibri, Arial; } </style> <script type="text/javascript"> window.history.forward(); function noBack() { window.history.forward(); } </script> </head> <body onload="noBack();" onpageshow="if (event.persisted) noBack();" onunload=""> <H2>Demo</H2> <p>This page contains the code to avoid Back button.</p> <p>Click here to Goto <a href="noback.html">NoBack Page</a></p> </body> </html> 

这篇关于jordanhollinger.com的文章是我感觉最好的select。 类似于剃刀的回答,但更清楚一点。 下面的代码; 完整的信用约旦霍林格:

页面之前:

 <a href="/page-of-no-return.htm#no-back>You can't go back from the next page</a> 

没有回报的JavaScript页面:

 // It works without the History API, but will clutter up the history var history_api = typeof history.pushState !== 'undefined' // The previous page asks that it not be returned to if ( location.hash == '#no-back' ) { // Push "#no-back" onto the history, making it the most recent "page" if ( history_api ) history.pushState(null, '', '#stay') else location.hash = '#stay' // When the back button is pressed, it will harmlessly change the url // hash from "#stay" to "#no-back", which triggers this function window.onhashchange = function() { // User tried to go back; warn user, rinse and repeat if ( location.hash == '#no-back' ) { alert("You shall not pass!") if ( history_api ) history.pushState(null, '', '#stay') else location.hash = '#stay' } } } 

这似乎已经在我们禁用浏览器的后退button,以及backspacebutton带你回来。

 history.pushState(null, null, $(location).attr('href')); window.addEventListener('popstate', function () { history.pushState(null, null, $(location).attr('href')); }); 
  history.pushState(null, null, location.href); window.onpopstate = function () { history.go(1); }; 

轻松尝试:

 history.pushState(null, null, document.title); window.addEventListener('popstate', function () { history.pushState(null, null, document.title); }); 
  <script src="~/main.js" type="text/javascript"></script> <script type="text/javascript"> window.history.forward(); function noBack() { window.history.forward(); } </script> 
 <script language="JavaScript"> javascript:window.history.forward(1); </script> 

试试这个以防止在IE中退格button,默认为“后退”:

 <script language="JavaScript"> $(document).ready(function() { $(document).unbind('keydown').bind('keydown', function (event) { var doPrevent = false; if (event.keyCode === 8 ) { var d = event.srcElement || event.target; if ((d.tagName.toUpperCase() === 'INPUT' && ( d.type.toUpperCase() === 'TEXT' || d.type.toUpperCase() === 'PASSWORD' || d.type.toUpperCase() === 'FILE' || d.type.toUpperCase() === 'EMAIL' || d.type.toUpperCase() === 'SEARCH' || d.type.toUpperCase() === 'DATE' ) ) || d.tagName.toUpperCase() === 'TEXTAREA') { doPrevent = d.readOnly || d.disabled; } else { doPrevent = true; } } if (doPrevent) { event.preventDefault(); } try { document.addEventListener('keydown', function (e) { if ((e.keyCode === 13)){ // alert('Enter keydown'); e.stopPropagation(); e.preventDefault(); } }, true); } catch (err) {} }); }); </script> 

非常简单和干净的function,打破后箭头,而不会干扰页面后。

优点:

  • 立即加载并恢复原始散列,所以用户不会被URL明显改变分心。
  • 用户仍然可以退出10次(这是件好事),但不是偶然的
  • 没有像使用onbeforeunload其他解决scheme的用户干扰
  • 它只运行一次,不会干扰进一步的散列操作,以防您使用它来跟踪状态
  • 恢复原始散列,因此几乎不可见。
  • 使用setInterval因此它不会中断浏览器的慢速运行。
  • 纯Javascript,不需要HTML5历史,无处不在。
  • Unobrusive,简单,并与其他代码很好地发挥。
  • 不使用用modal dialog中断用户的unbeforeunload
  • 它只是没有大惊小怪。

注意:一些其他解决scheme使用onbeforeunload 。 请不要使用onbeforeunload来达到这个目的,当用户试图closures窗口,重击等等时,popup一个对话框。像onbeforeunload这样的模式通常只适用于极less数情况下,比如当他们实际上在屏幕上做了改变,没有保存他们,不是为了这个目的。

怎么运行的

  1. 执行页面加载
  2. 保存您的原始散列(如果一个在URL中)。
  3. 按顺序将#/ noop / {1..10}追加到散列
  4. 恢复原始散列

而已。 没有进一步的混乱,没有后台事件监控,没有别的。

在一秒钟内使用它

要进行部署,只需将其添加到您的页面或JS中的任意位置:

 <script> /* break back button */ window.onload=function(){ var i=0; var previous_hash = window.location.hash; var x = setInterval(function(){ i++; window.location.hash = "/noop/" + i; if (i==10){clearInterval(x); window.location.hash = previous_hash;} },10); } </script> 

我创build了一个HTML页面(index.html)。 我还在(脚本)文件夹/目录内创build一个(mechanism.js)。 然后,根据需要使用form,table,span和div标签将所有内容放在(index.html)中。 现在,这个诀窍将使得回退/前进无所事事!

首先,你只有一个页面的事实! 其次,使用带有span / div标签的JavaScript通过常规链接在需要的时候在同一页面上隐藏和显示内容!

在'index.html'里面:

  <td width="89px" align="right" valign="top" style="letter-spacing:1px;"> <small> <b> <a href="#" class="traff" onClick="DisplayInTrafficTable();">IN</a>&nbsp; </b> </small> [&nbsp;<span id="inCountSPN">0</span>&nbsp;] </td> 

在'mechanism.js'里面:

  function DisplayInTrafficTable() { var itmsCNT = 0; var dsplyIn = ""; for ( i=0; i<inTraffic.length; i++ ) { dsplyIn += "<tr><td width='11'></td><td align='right'>" + (++itmsCNT) + "</td><td width='11'></td><td><b>" + inTraffic[i] + "</b></td><td width='11'></td><td>" + entryTimeArray[i] + "</td><td width='11'></td><td>" + entryDateArray[i] + "</td><td width='11'></td></tr>"; } document.getElementById('inOutSPN').innerHTML = "" + "<table border='0' style='background:#fff;'><tr><th colspan='21' style='background:#feb;padding:11px;'><h3 style='margin-bottom:-1px;'>INCOMING TRAFFIC REPORT</h3>" + DateStamp() + "&nbsp;&nbsp;-&nbsp;&nbsp;<small><a href='#' style='letter-spacing:1px;' onclick='OpenPrintableIn();'>PRINT</a></small></th></tr><tr style='background:#eee;'><td></td><td><b>###</b></td><td></td><td><b>ID #</b></td><td></td><td width='79'><b>TYPE</b></td><td></td><td><b>FIRST</b></td><td></td><td><b>LAST</b></td><td></td><td><b>PLATE #</b></td><td></td><td><b>COMPANY</b></td><td></td><td><b>TIME</b></td><td></td><td><b>DATE</b></td><td></td><td><b>IN / OUT</b></td><td></td></tr>" + dsplyIn.toUpperCase() + "</table>" + ""; return document.getElementById('inOutSPN').innerHTML; } 

它看起来很毛茸茸,但请注意函数名称和调用,embedded的HTML和span标记id调用。 这是为了展示如何在同一页面上将不同的HTML注入到相同的span标记中! 后退/前进如何影响这种devise? 它不能,因为你隐藏的对象和replace所有在同一页上的其他人!

如何隐藏和显示? 这里是:根据需要在'mechanism.js'里面的函数,使用:

  document.getElementById('textOverPic').style.display = "none"; //hide document.getElementById('textOverPic').style.display = ""; //display 

在'index.html'里面通过链接调用函数:

  <img src="images/someimage.jpg" alt="" /> <span class="textOverPic" id="textOverPic"></span> 

  <a href="#" style="color:#119;font-size:11px;text-decoration:none;letter-spacing:1px;" onclick="HiddenTextsManager(1);">Introduction</a> 

我希望我没有让你头痛。 对不起,如果我做到了:-)

在我的情况下,这是一个购物订单。 所以我做的是禁用button。 当用户点击后,该button仍被禁用。 当他们再次点击一下,然后点击一个页面button前进。 我知道他们的订单已经提交并跳到另一页。

在页面实际刷新的情况下,会使button(理论上)可用; 然后,我可以在订单已经提交并redirect的页面加载中作出反应。

我相信这个完美的解决scheme其实很简单,我已经使用了很多年了。

它基本上是将窗口的“onbeforeunload”事件与正在进行的文档“mouseenter”/“mouseleave”事件一起分配,所以当点击超出文档范围时(这可以是浏览器的后退或前进button)

 $(document).on('mouseenter', function(e) { window.onbeforeunload = null; } ); $(document).on('mouseleave', function(e) { window.onbeforeunload = function() { return "You work will be lost."; }; } ); 

你根本不能也不应该这样做。 但是,这可能会有所帮助

 <script type = "text/javascript" > history.pushState(null, null, 'pagename'); window.addEventListener('popstate', function(event) { history.pushState(null, null, 'pagename'); }); </script> 

在我的Chrome和Firefox中工作

 //"use strict"; function stopBackSpace(e) { var ev = e || window.event; var obj = ev.target || ev.srcElement; var t = obj.type || obj.getAttribute('type'); var vReadOnly = obj.getAttribute('readonly'); var vEnabled = obj.getAttribute('enabled'); // null vReadOnly = (vReadOnly == null) ? false : vReadOnly; vEnabled = (vEnabled == null) ? true : vEnabled; // when click Backspace,judge the type of obj. var flag1 = ((t == 'password' || t == 'text' || t == 'textarea') && ((vReadOnly == true || vReadOnly == 'readonly') || vEnabled != true)) ? true : false; var flag2 = (t != 'password' && t != 'text' && t != 'textarea') ? true : false; if (flag2) { e.keyCode = 0; e.cancelBubble = true; return false; } if (flag1) { e.keyCode = 0; e.cancelBubble = true; return false; } } if (typeof($) == 'function') { $(function() { $(document).keydown(function(e) { if (e.keyCode == 8) { return stopBackSpace(e); } }); }); } else { document.onkeydown = stopBackSpace; }