Javascript 测量输入时间

Javascript 测量输入时间,javascript,jquery,time,measure,Javascript,Jquery,Time,Measure,我有一个简单的测验表格,有几个输入和选择,我需要测量参赛者写/选择答案所花的时间 这是我正在尝试的,但它报告的时间不正确: $('input,select')。在('focus',函数(event)上{ el=$(本); name=el.attr('name');//console.log(name); a=性能。现在(); a_值=el.val(); console.log(name+“focused.”); $(el).on('输入选择剪切复制粘贴',函数(事件){ console.log

我有一个简单的测验表格,有几个输入和选择,我需要测量参赛者写/选择答案所花的时间

这是我正在尝试的,但它报告的时间不正确:

$('input,select')。在('focus',函数(event)上{
el=$(本);
name=el.attr('name');//console.log(name);
a=性能。现在();
a_值=el.val();
console.log(name+“focused.”);
$(el).on('输入选择剪切复制粘贴',函数(事件){
console.log('el:'+el);
b_值=el.val();
如果(a_值!=b_值){
b=性能。现在();
如果(名称以时间为单位){
log('exists');
倍[名称]=倍[名称]+(b-a);
}否则{
倍[名称]=b-a;
}
}
});
$(el).on('blur',函数(事件){
警报(次);
});
});

JS-Bin
选择1
选择2
试试这个

<script>
  var Stopwatch = (function() {
            var s;
            return {
                settings: {
                    stop: 0,
                    sw: document.querySelectorAll(".stopwatch")[0],
                    results: document.querySelectorAll(".results")[0],
                    mills: 0,
                    secs: 0,
                    mins: 0,
                    i: 1,
                    times: ["00:00:00"],
                    clearButton: "<a href=\"#\" class=\"button\" onClick=\"Stopwatch.clear();\">Clear</a>"
                },
                init: function() {
                    s = this.settings;
                    setInterval(this.timer, 1);
                },
                clear: function() {
                    s.i = 1,
                    s.times = ["00:00:00"],
                    s.results.innerHTML = s.clearButton;
                },
                lap: function() {
                    if (s.i === 1) {
                        s.results.innerHTML = s.clearButton;
                    }
                    s.times.push(("0" + s.mins).slice(-2) + ":"
                                         + ("0" + s.secs).slice(-2) + ":"
                                         + ("0" + s.mills).slice(-2));
                    var diffTime = ("0" + Math.floor(s.times[s.i].split(":")[0]
                                             - s.times[s.i-1].split(":")[0])).slice(-2)
                                             + ":"
                                             + ("0" + Math.floor(s.times[s.i].split(":")[1]
                                             - s.times[s.i-1].split(":")[1])).slice(-2)
                                             + ":"
                                             + ("0" + (s.times[s.i].split(":")[2]
                                             - s.times[s.i-1].split(":")[2])).slice(-2);
                    s.results.innerHTML = s.results.innerHTML + "<tr><td>"
                                                            + s.times[s.i] + "</td><td>"
                                                            + diffTime + "</td></tr>";
                    s.i++;
                },
                restart: function() {
                    s.mills = 0,
                    s.secs = 0,
                    s.mins = 0;
                    this.start();
                },
                start: function() {
                    s.stop = 0;
                },
                stop: function() {
                    s.stop = 1;
                },
                timer: function() {
                    if (s.stop === 0) {
                        if (s.mills === 100) {
                            s.secs++;
                            s.mills = 0;
                        }
                        if (s.secs === 60) {
                            s.mins++;
                            s.secs = 0;
                        }
                        s.sw.innerHTML = ("0" + s.mins).slice(-2) + ":"
                                                     + ("0" + s.secs).slice(-2) + ":"
                                                     + ("0" + s.mills).slice(-2);
                        s.mills++;
                    }
                }
            };
        })();
$('.textbox,.selectbox').focusin(function(event) {
 Stopwatch.init();
Stopwatch.restart();    
});
$('.textbox,.selectbox').on('blur', function(event) {
    Stopwatch.stop();
});

var Stopwatch=(函数(){
var s;
返回{
设置:{
停止:0,,
sw:document.queryselectoral(“.stopwatch”)[0],
结果:document.querySelectorAll(“.results”)[0],
米尔斯:0,
秒:0,
分钟:0,
一:1,,
时间:[“00:00:00”],
clearButton:“
},
init:function(){
s=此参数设置;
设置时间间隔(此计时器为1);
},
清除:函数(){
s、 i=1,
s、 时间=[“00:00:00”],
s、 results.innerHTML=s.clearButton;
},
lap:函数(){
如果(s.i==1){
s、 results.innerHTML=s.clearButton;
}
s、 推送时间((“0”+s.mins)。切片(-2)+:“
+(“0”+s.secs)。切片(-2)+”:”
+(“0”+s.mills)。切片(-2));
var diffTime=(“0”+Math.floor(s.times[s.i]。拆分(“:”[0]
-s.times[s.i-1]。拆分(“:”[0])。切片(-2)
+ ":"
+(“0”+数学层(s.times[s.i.)。拆分(“:”[1]
-s.times[s.i-1]。拆分(“:”[1])。切片(-2)
+ ":"
+(“0”+(s.times[s.i.)。拆分(“:”[2]
-s.times[s.i-1]。拆分(“:”[2])。切片(-2);
s、 results.innerHTML=s.results.innerHTML+“”
+s.times[s.i]+“”
+diffTime+“”;
s、 i++;
},
重新启动:函数(){
s、 米尔斯=0,
s、 秒=0,
s、 分钟=0;
这个。start();
},
开始:函数(){
s、 停止=0;
},
停止:函数(){
s、 停止=1;
},
计时器:函数(){
如果(s.stop==0){
如果(s.mills==100){
s、 secs++;
s、 米尔斯=0;
}
如果(秒=60){
s、 mins++;
s、 秒=0;
}
s、 sw.innerHTML=(“0”+s.mins).slice(-2)+:“
+(“0”+s.secs)。切片(-2)+”:”
+(“0”+s.mills)切片(-2);
s、 米尔斯++;
}
}
};
})();
$('.textbox,.selectbox').focusin(函数(事件){
Stopwatch.init();
Stopwatch.restart();
});
$('.textbox、.selectbox')。在('blur',函数(事件)上{
秒表;
});


你可以找到我试过的东西。 对我来说主要的一点是,你一次又一次地计算时间,因为最初的时间没有改变,而且你不止一次地增加了回答时间

if (name in times) {
    console.log('exists');
    times[name] = times[name] + (b - a);
    //here you already had added (b1 - a) with b1 < b
    //either you reset 'a' here or you store the diff in a variable and sum it up at the end
} else {
    times[name] = b - a;
}
if(名称以时间为单位){
log('exists');
倍[名称]=倍[名称]+(b-a);
//这里您已经添加了(b1-a)和b1
我将应答时间存储在一个变量中,并将其添加到
blur
上的数组中,并尝试尽可能与原始方法保持一致

不过,我还是错过了一些东西。这主要与作弊有关。就我所知,你只想计算真正的变化时间(从
焦点
到最后一次
输入
,比方说,不计算从最后一次
输入
模糊
的时间,当然也不计算查看页面和可能在写字板环境中编写答案的时间)

在一个公平而安全的系统中,你应该考虑到,有人能比他实际写的答案更多地看测验。但这显然取决于测验的目的

在与您(OP)交谈之后,我对您的基本代码进行了几次调整

首先,每次表单元素有焦点时都会调用
.on('input…')
,因此事件处理程序会堆积起来。在模糊处理程序中调用相应的
.off('input…')
来处理此问题

接下来,创建一个关联
(function () {
    var getTime = function () { return performance.now(); };
    function MeasureTime () {
        this.editTimes = [];
        this.currentEdit = null;
        this.lastEdit = {start:0, last: 0};
        this.firstEdit = 0;
    }
    MeasureTime.prototype = {
        setFirst: function () {
            this.firstEdit = getTime();
            this.setFirst = new Function();
        },
        startEdit: function (val) {
            this.setFirst();
            if(this.currentEdit == null) {
                this.currentEdit = {start: getTime(), last: getTime(), value: val};
                this.editTimes.push(0);
            } else {
                this.edit(val);
            }
        },
        edit: function (val) {
            if(this.currentEdit == null)
                  this.startEdit(val);
            else {
                var current = this.currentEdit;
                if(current.value == val)
                    return;
                current.last = getTime();
                this.editTimes.pop();
                this.editTimes.push(current.last - current.start);
            }
        },
        stopEdit: function () {
            if(this.currentEdit != null) {
                this.lastEdit = this.currentEdit;
                this.currentEdit = null;
            }
        },
        getEvent: function () {
            return new TimeMeasuredEvent(this.editTimes, this.currentEdit || this.lastEdit, this.firstEdit);
        }
    };
    function TimeMeasuredEvent (all, current, first) {
        this.all = all.slice(0);
        this.start = current.start;
        this.last = current.last;
        this.first = first;
    }
    TimeMeasuredEvent.prototype = {
        current: function () {
            return this.all[this.all.length-1];
        },
        total: function () {
            var sum = 0, a = this.all, l = a.length, i = -1;
            while(++i<l)
                sum+=a[i];
            return sum;
        }
    };
    function EnsureMeasureTime () {
        if (typeof(this.measureTimeData) === "undefined") {
            var mtd = this.measureTimeData = new MeasureTime();
            $(this).on('focus', function () {
                mtd.startEdit(this.value);
        $(this).on('input.measuretime select.measuretime cut.measuretime copy.measuretime paste.measuretime', function () {
           mtd.edit(this.value);
           $(this).trigger('timeMeasured', [mtd.getEvent()]); 
        });
            $(this).on('blur', function () {
                mtd.stopEdit();
                $(this).trigger('timeMeasured', [mtd.getEvent()]); 
                $(this).off('measuretime');
            });
        });
        }
    }
    $.fn.measureTime = function () {
        $(this).each(EnsureMeasureTime);
        return this;
    };
})();
var inputs = $('input, select');
inputs.measureTime();
var all = {};
inputs.on('timeMeasured', function (ev, data) {
    console.log(ev, data);
    all[ev.target.name] = data.total();
    console.log("First edit time: " + data.first);
    console.log("Last edit time: " + data.last);
    console.log("All edits durations: " + data.all.join(", "));
    console.log("Current edit duration: " + data.current());
    console.log("Total edit duration: " + data.total());
    var s = "";
    for(var n in all) {
        s+= n + ": " + all[n]+"\n";
    }
    $("#times").text(s);
});