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 个对象:
钥匙
键盘
键盘监听器
他们言出必行。
如果你需要任何解释,请告诉我。
哦,有一件事,我知道你不应该像这样使用数组,但我很懒。
我正在 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 个对象:
钥匙 键盘 键盘监听器
他们言出必行。
如果你需要任何解释,请告诉我。
哦,有一件事,我知道你不应该像这样使用数组,但我很懒。