阻止js alert()暂停定时器

时间:2008-10-13 15:47:23

标签: javascript timer

所以我做了一些测验计时器。问题是,当我把

时,我才意识到
javascript: alert("blah");

在地址中,弹出警告框暂停我的计时器。在测验中这是非常不需要的。

我认为没有办法阻止这种行为......但无论如何我都会问。

如果没有,请记住我应该怎么做?

8 个答案:

答案 0 :(得分:10)

永远不要依赖javascript(或任何其他客户端时间)来计算回发或不同页面之间完成的操作所经过的时间。

如果您总是比较服务器日期,那么人们很难作弊:

  1. 第一页请求,存储服务器时间
  2. 使用javascript调用ping每N秒,比较2个服务器时间,并返回已用时间(仅用于显示)
  3. 当用户提交表单时,比较2个服务器时间,计算经过的时间,并丢弃花费时间过长的时间(即:可能的欺骗者)

答案 1 :(得分:6)

显然,预览渲染与发布的渲染不同。这一段是为了确保接下来的两行显示为代码。

// Preserve native alert() if you need it for something special
window.nativeAlert = window.alert;

window.alert = function(msg) {
    // Do something with msg here. I always write mine to console.log,
    // but then I have rarely found a use for a real modal dialog,
    // and most can be handled by the browser (like window.onbeforeunload).
};

答案 2 :(得分:5)

不,没有办法阻止警报停止JavaScript中的单个线程。可能您可以使用其他一些用户通知方式,例如浮动图层。

答案 3 :(得分:3)

这是模态并停止执行。考虑一种不像Lightbox技术那样暂停执行的替代方案。

答案 4 :(得分:3)

我认为提问者正在努力防止作弊。由于用户可以输入javascript:alert(“暂停”);进入地址栏,或制作一个书签来做到这一点,很容易暂停测验和作弊。

我唯一能想到的是使用Date()获取当前时间,并在计时器触发时再次检查。然后,如果时间差不合理地接近预定的计时器持续时间,则显示警告并取消该问题的答案或让他们不及测验。没有办法阻止用户暂停您的测验,但应该可以捕获它们。

当然,如果有任何作弊行为,你会激励人们成为更好的骗子。一个人可以在他们的PC上改变系统时间,并欺骗javascript Date()构造函数,它从操作系统中获取时间。

您可以使用间隔对一秒间隔长度进行重复时钟比较。间隔处理程序还可以更新用户显示屏上的剩余时间字段。然后,用户可以在测验时耗尽时感受压力。有趣的时光!

答案 5 :(得分:2)

SyaZ问题的反馈循环澄清了所涉及的问题。

这是尝试总结目前为止的好答案:

  • 客户端脚本本质上易于操纵以欺骗在线测验。见@Filini 's Server-side approach

  • window.alert = function(msg){}将覆盖 alert()并且可能会打败放入地址栏的低成果: javascript:alert('暂停页面,所以我可以谷歌答案')或我现在将使用我的电话朋友。 Courtesy of @eyelidlessness

  • 如果你必须使用客户端方法,而不是使用setTimeOut(),你可以使用这样的自定义基于日期比较的暂停函数(concept by @Mnebuerquo,代码示例由我({ {3}})):

示例:

var beginDate = new Date();

function myTimeout(milsecs){
  do { curDate = new Date(); }
    while((curDate-beginDate) < milsecs);
}

function putDownYourPencils(milsecs){
  myTimeout(milsecs);
  var seconds = milsecs / 1000;
  alert('Your '  + seconds + ' seconds are up. Quiz is over.');
}

putDownYourPencils(3000);

答案 6 :(得分:2)

最终,您无法信任用户输入。如果不跟踪服务器上的时间,就不能保证数据没有被操纵。

但是,如果你确信你的测验者并不精通JavaScript,只是依赖于他们在某个地方找到的“技巧”,你可以用下面的代码测试作弊(暂停),需要修改window.alert:

var timer = {
    startDatetime: null,
    startSec: 0,
    variance: 1,
    exitOnPause: true,
    count: function (config) {
        var that = this;

        if (typeof config == "object" && typeof parseInt(config.seconds) == "number" && !isNaN(parseInt(config.seconds)))
        {
            if (typeof parseFloat(config.variance) == "number" && !isNaN(parseFloat(config.variance))) this.variance = config.variance;
            if (typeof config.exitOnPause == "boolean") this.exitOnPause = config.exitOnPause;

            if (config.seconds > 0)
            {
                if (!this.startSec) this.startSec = config.seconds;
                if (!this.startDatetime) this.startDatetime = new Date();
                var currentDatetime = new Date();

                if (currentDatetime.getTime() - this.startDatetime.getTime() > (this.startSec - config.seconds) * this.variance * 1000)
                {
                    if (typeof config.onPause == "function") config.onPause();

                    if (!this.exitOnPause)
                    {
                        this.startDatetime = new Date();
                        this.startSec = config.seconds--;
                        window.setTimeout(function () { that.count(config); }, 1000);
                    }
                }
                else
                {
                    config.seconds--;
                    window.setTimeout(function () { that.count(config); }, 1000);
                }
            }
            else
            {
                if (typeof config.onFinish == "function") config.onFinish();
            }
        }
    }
};

此计时器对象有一个方法count(),它接受一个对象作为输入。它期望输入对象中的seconds属性至少为。

由于某种原因,window.setTimeout并不总是按预期工作。有时,在我的机器上,window.setTimeout(x,1000),它应该在1秒后执行代码,花费超过2秒。所以,在这样的情况下,你应该允许变化,所以没有作弊的人不会被标记为骗子。方差默认为1,但可以在输入对象中覆盖它。以下是如何使用此代码的示例,该代码允许2.5秒的“摆动空间”用于慢速戳:

timer.count({
    seconds: 10,
    onPause: function () { alert("You cheated!"); window.location.replace("cheatersAreBad.html"); },
    onFinish: function () { alert("Time's up!"); },
    variance: 2.5
});

使用这样的解决方案,您可以使用Ajax告诉服务器端脚本用户已暂停计时器或将用户重定向到一个页面,例如说明他们被发现作弊。如果由于某种原因,你想让用户在被发现作弊后继续参加测验,你可以将exitOnPause设置为false:

timer.count({
    seconds: 10,
    exitOnPause: false,
    onPause: function () { recordCheaterViaAjax(); },
    onFinish: function () { alert("Time's up!"); },
    variance: 2.5
});

答案 7 :(得分:0)

服务器会话可以设置为在1小时后到期。 javascript可以仅用作显示工具,以便用户知道还剩多少时间。如果他决定通过暂停计时器来作弊,那么在发布他的会话已经超时的测试时他可能会感到惊讶。