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


当前回答

重写web浏览器的默认行为通常不是一个好主意。出于安全原因,客户端脚本没有足够的特权来执行此操作。

还有一些类似的问题,

如何防止退格键导航回? 我如何可以防止浏览器的默认历史后退动作退格按钮与JavaScript?

你不能禁用浏览器的后退按钮。然而,你可以使用你的逻辑来阻止用户返回,这将创造一个像它被禁用的印象。这是如何-检查以下片段。

(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 the event bubbling up the DOM tree...
            e.stopPropagation();
        };
    }
})(window);

这是纯JavaScript,所以它可以在大多数浏览器中工作。它也会禁用退格键,但该键将在输入字段和文本区域内正常工作。

建议设置:

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

工作演示!

它在以下浏览器中进行了测试和验证,

铬。 Firefox。 ie浏览器(8-11)和Edge。 Safari。

其他回答

在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+中的返回。

重写web浏览器的默认行为通常不是一个好主意。出于安全原因,客户端脚本没有足够的特权来执行此操作。

还有一些类似的问题,

如何防止退格键导航回? 我如何可以防止浏览器的默认历史后退动作退格按钮与JavaScript?

你不能禁用浏览器的后退按钮。然而,你可以使用你的逻辑来阻止用户返回,这将创造一个像它被禁用的印象。这是如何-检查以下片段。

(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 the event bubbling up the DOM tree...
            e.stopPropagation();
        };
    }
})(window);

这是纯JavaScript,所以它可以在大多数浏览器中工作。它也会禁用退格键,但该键将在输入字段和文本区域内正常工作。

建议设置:

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

工作演示!

它在以下浏览器中进行了测试和验证,

铬。 Firefox。 ie浏览器(8-11)和Edge。 Safari。

它基本上是分配窗口的“onbeforeunload”事件以及正在进行的文档“mouseenter”/“mouseleave”事件,因此警报只在单击超出文档范围时触发(然后可以是浏览器的后退或前进按钮)

美元(文档)。On ('mouseenter',函数(e) { 窗口。Onbeforeunload = null; } ); 美元(文档)。On ('mouseleave',函数(e) { 窗口。onbeforeunload = function(){返回"你的工作将会丢失";}; } );

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

我为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);
    };
  }, []);

基于@Franklin Innocent F的回答

Kotlin/JS (React)的解决方案:

import org.w3c.dom.events.Event
import kotlin.browser.document
import kotlin.browser.window

...
override fun componentDidMount() {
    window.history.pushState(null, "", window.location.href)
    window.history.back()
    window.history.forward()
    window.addEventListener("popstate", browserBackButtonHandler)
}

...
private val browserBackButtonHandler: (Event?) -> Unit = {
    window.history.go(1)
}