如何停止使用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的方法,但不保证:
覆盖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数情况下,比如当他们实际上在屏幕上做了改变,没有保存他们,不是为了这个目的。
怎么运行的
- 执行页面加载
- 保存您的原始散列(如果一个在URL中)。
- 按顺序将#/ noop / {1..10}追加到散列
- 恢复原始散列
而已。 没有进一步的混乱,没有后台事件监控,没有别的。
在一秒钟内使用它
要进行部署,只需将其添加到您的页面或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> </b> </small> [ <span id="inCountSPN">0</span> ] </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() + " - <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; }