我正在用PHP做一个在线测试应用程序。我想限制用户在考试中返回。

我尝试了下面的脚本,但它停止了我的计时器。

我该怎么办?

定时器存储在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值中获取考试的持续时间。计时器随之启动,但当我输入禁用后退按钮的代码时,它就停止了。我有什么问题?


当前回答

我觉得jordanhollinger.com上的这篇文章是最好的选择。与Razor的答案相似,但更清楚一些。下面的代码;全部归功于Jordan Hollinger:

页面:

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

no return的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'
    }
  }
}

其他回答

<script>
    window.location.hash = "no-back-button";

    // Again because Google Chrome doesn't insert
    // the first hash into the history
    window.location.hash = "Again-No-back-button"; 

    window.onhashchange = function(){
        window.location.hash = "no-back-button";
    }
</script>

这似乎在禁用浏览器上的后退按钮,以及退格键带你回到工作。

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

这段代码是完整的javascript。 把这个放在你的主页或者其他你需要的地方当有人返回时,它会把他们带到他们之前所在的页面。

<script type="text/javascript"> 
        function preventBack() { 
            window.history.forward();  
        } 
          
        setTimeout("preventBack()", 0); 
          
        window.onunload = function () { null }; 
    </script>

在Chrome 79中,被点赞最多的答案没有一个对我有效。看起来Chrome在75版之后改变了后退按钮的行为。在这里看到的:

https://support.google.com/chrome/thread/8721521?hl=en

然而,在谷歌的帖子中,Azrulmukmin Azmi在最后提供的答案确实起作用了。这是他的解。

<script>
    history.pushState(null, document.title, location.href);
    history.back();
    history.forward();
    window.onpopstate = function () {
        history.go(1);
    };
</script>

Chrome的问题是它不会触发onpopstate事件 除非你做出浏览器动作(即调用history.back)。这就是为什么 我已经将这些添加到脚本中。

我不完全明白他写了什么,但显然现在需要一个额外的history.back() / history.forward()来阻止Chrome 75+中的返回。

这里的一些解决方案不会阻止回退事件的发生——它们让回退事件发生(浏览器内存中关于页面的数据丢失),然后它们播放一个向前事件,试图隐藏回退事件刚刚发生的事实。如果页面处于暂时状态,则该方法将不成功。

我为React写了这个解决方案(当React路由器不被使用时),它是基于vrfvr的答案。

它将真正阻止后退按钮做任何事情,除非用户确认弹出:

  const onHashChange = useCallback(() => {
    const confirm = window.confirm(
      'Warning - going back will cause you to loose unsaved data. Really go back?',
    );
    window.removeEventListener('hashchange', onHashChange);
    if (confirm) {
      setTimeout(() => {
        window.history.go(-1);
      }, 1);
    } else {
      window.location.hash = 'no-back';
      setTimeout(() => {
        window.addEventListener('hashchange', onHashChange);
      }, 1);
    }
  }, []);

  useEffect(() => {
    window.location.hash = 'no-back';
    setTimeout(() => {
      window.addEventListener('hashchange', onHashChange);
    }, 1);
    return () => {
      window.removeEventListener('hashchange', onHashChange);
    };
  }, []);