所以我做了一些测验计时器。问题是,当我把
时,我才意识到javascript: alert("blah");
在地址中,弹出警告框暂停我的计时器。在测验中这是非常不需要的。
我认为没有办法阻止这种行为......但无论如何我都会问。
如果没有,请记住我应该怎么做?
答案 0 :(得分:10)
永远不要依赖javascript(或任何其他客户端时间)来计算回发或不同页面之间完成的操作所经过的时间。
如果您总是比较服务器日期,那么人们很难作弊:
答案 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可以仅用作显示工具,以便用户知道还剩多少时间。如果他决定通过暂停计时器来作弊,那么在发布他的会话已经超时的测试时他可能会感到惊讶。