Javascript - 记录用户在整个访问期间按下给定按钮的时间

Javascript - register how long user pressed a given button during whole visit

我正在 Qualtrics 中编写实验程序,我基本上需要使用 Javascript 创建一个变量,告诉我参与者按下任何按钮的时间(总计)。按下一个按钮会向参与者显示文本,松开按钮会使文本消失,所以基本上它会告诉我他们有多少时间阅读文本。所以假设他们按下按钮三次,第一次 30 秒,第二次 10 秒,第三次 2 秒,这段代码应该存储值 42.

我目前的情况是这样的:

addEventListener("keydown", function(event) {
if (event.keyCode == 86)
    document.getElementById("text").innerHTML = "Text to show";
    var d1 = new Date();
    document.getElementById("div1").innerHTML = d1.getTime(); 

});
addEventListener("keyup", function(event) {
if (event.keyCode == 86)
    document.getElementById("text").innerHTML = "";
    var d2 = new Data();
    var d1 = parseFloat(document.getElementById("div1"));
    var diff = d2 - d1.getTime();
    var old = parseFloat(document.getElementById("div2"));
    var old = old + diff;
    document.getElementById("div2").innerHTML = old;        
    Qualtrics.SurveyEngine.setEmbeddedData("readingtime", totalTime);
});

我将值存储在 div 中,因为我似乎无法将一个事件侦听器的值重用到另一个事件侦听器(这可能是因为我对 javascript 和范围了解不够)。哦,最后一个函数只是一个特定于 Qualtrics 的函数,用于将值存储在数据库中。无论如何,我无法让它工作,当我检查数据库中的变量时,它只是空的。任何人都可以发现我做错了什么?

您可以尝试在侦听器和函数外部创建一个变量,这样您就可以在任何地方使用它。 而且我认为您通过获取日期时间做得很好。

var firstTime = new Date();
var totalTime = 0;

addEventListener("keydown", function(event) {
if (event.keyCode == 86) {
    document.getElementById("text").innerHTML = "Text to show";
    firstTime = new Date();
}
});
addEventListener("keyup", function(event) {
if (event.keyCode == 86) {
    document.getElementById("text").innerHTML = "";
    var d2 = new Date();
    var diff = d2.getTime() - firstTime.getTime();
    totalTime += diff;

    Qualtrics.SurveyEngine.setEmbeddedData("readingtime", totalTime);
}
});

"totalTime" 在哪里分配?

你的totalTime值吗? 您是否尝试使用浏览器控制台调试 javascript?

如果您不想将数据存储到 div,您可以将其存储在全局变量中。

var times = {
    start: 0,
    total: 0
}

addEventListener("keydown", function(event) {
    if (event.keyCode == 86) { 
        // i think your hole code should be executed only on releasing this one button
        document.getElementById("text").innerHTML = "Text to show";
        times.start = new Date();
    }
});

addEventListener("keyup", function(event) {
    if (event.keyCode == 86) {
        // i think your hole code should be executed only on releasing this one button
        document.getElementById("text").innerHTML = "";
        var diff = new Date().getTime() - times.start.getTime();
        times.total = times.total + diff;
        Qualtrics.SurveyEngine.setEmbeddedData("readingtime", times.total);
    }
});

因此您可以在事件侦听器函数之外使用 var times 将其声明为全局。

我注意到你使用了 if ().. 而没有 { 和 },所以只有下一行受到影响,如果你想要的话我不放心。

最好将 d1 和 d2 变量声明为全局变量,而不是使用 html 元素作为存储。

var d1, d2;
var total_time = 0;
var key_pressed = false;

addEventListener("keydown", function(event) {
    if (event.keyCode == 86) {
        if (!key_pressed)
           d1 = new Date();
        key_pressed = true;
    }   
});

addEventListener("keyup", function(event) {
    if (event.keyCode == 86) {
        key_pressed = false;
        d2 = new Date();
        total_time += d2.getTime() - d1.getTime();
        Qualtrics.SurveyEngine.setEmbeddedData("readingtime", total_time);   
    }
});

按住'v'键时,会重复调用keydown监听器。这就是为什么有布尔变量,即 "key_pressed" 第一次检测保持键。

我对你的代码做了一些修改:

  • 添加了全局变量
  • 添加了几个缺失的括号
  • 已将侦听器附加到 window
  • 删除了对 DOM 个元素的多次调用
  • 为每个事件侦听器创建了一个函数
  • 经过的时间四舍五入为秒

var d0;
var d1;

var subtotal = 0;
var total = 0;

var div1 = document.getElementById("div1");
var text = document.getElementById("text");

window.addEventListener("keydown", dealWithKeyDown, false);
window.addEventListener("keyup", dealWithKeyUp, false);

function dealWithKeyDown(event) {
    if (event.keyCode == 86) {

        if (typeof d0 === 'undefined') {
            d0 = new Date();
        }

        d1 = new Date();        
        subtotal = Math.round((d1.getTime() - d0.getTime()) / 1000);  

        div1.innerHTML = subtotal;
        text.innerHTML = "Text to show";
    }
}

function dealWithKeyUp(event) {
    if (event.keyCode == 86) {
        total = total + subtotal;
        text.innerHTML = "";
        d0 = undefined;       
        Qualtrics.SurveyEngine.setEmbeddedData("readingtime", total);
    }
}

好的,天啊,none 的 post 答案似乎已被接受,我要 post 我自己的答案。

关于这个解决方案真的没什么好说的,它很简单,很好地放入对象中,这样我们就知道发生了什么,我什至给你一个 fiddle !

有一个问题不知道解决了没有,但是有时候按钮会显示按下了百万秒,我觉得是key没有初始化好,很奇怪,但这种情况很少发生,以至于我无法将修复它的负担推给你。

代码在这里: https://jsfiddle.net/vo2n1jw1/

已粘贴:

var Key = function(code)
{
    this.code = code;
};

Key.prototype.time = 0;
Key.prototype.pressedAt = 0;

Key.prototype.getTimeInSeconds = function()
{
    return this.time / 1000;
};

var Keyboard = function()
{
    this.keys = [];
};

Keyboard.prototype.addOrGetKey = function(code)
{
    var key = this.getKey(code);

    if(!key)
    {
        key = new Key(code);

        this.addKey(key);
    }

    return key;
};

Keyboard.prototype.addKey = function(key)
{
    this.getKeys()[key.code] = key;
};

Keyboard.prototype.getKey = function(code)
{
    return this.getKeys()[code];
};

Keyboard.prototype.getKeys = function()
{
    return this.keys;
};

Keyboard.prototype.printAllKeysIntoElement = function(element)
{
    var keys = this.getKeys();
    var length = keys.length;

    element.innerHTML = "";

    for(var i = 0; i < length; i++)
    {
        var key = keys[i];

        if(!key)
        {
            continue;
        }

        var keyElement = document.createElement("div");
        keyElement.innerHTML = "Button: " + key.code + " has been pressed for " + key.getTimeInSeconds() + " seconds";

        element.appendChild(keyElement);
    }
};

var KeyboardListener = function(keyboard, element)
{
    this.keyboard = keyboard;
    this.container = element;

    this.onKeyDownThis = this.onKeyDown.bind(this);

    document.addEventListener("keydown", this.onKeyDownThis, false);
    document.addEventListener("keyup", this.onKeyUp.bind(this), false);
};

KeyboardListener.prototype.onKeyDown = function(event)
{
    console.log("press");

    var keyboard = this.getKeyboard();
    var code = event.keyCode;
    var key = keyboard.addOrGetKey(code);

    key.pressedAt = Date.now();

    document.removeEventListener("keydown", this.onKeyDownThis, false);

    return false;
};

KeyboardListener.prototype.onKeyUp = function(event)
{
    console.log("release");

    var keyboard = this.getKeyboard();
    var code = event.keyCode;
    var key = keyboard.addOrGetKey(code);

    if(key.pressedAt)
    {
        key.time += Date.now() - key.pressedAt;

        keyboard.printAllKeysIntoElement(this.container);
    }

    document.addEventListener("keydown", this.onKeyDownThis, false);

    return false;
};

KeyboardListener.prototype.getKeyboard = function()
{
    return this.keyboard;
};

var resultsElement = document.getElementById("results");

var keyboard = new Keyboard();
var listener = new KeyboardListener(keyboard, resultsElement);

有 3 个对象:

钥匙 键盘 键盘监听器

他们言出必行。

如果你需要任何解释,请告诉我。

哦,有一件事,我知道你不应该像这样使用数组,但我很懒。