TL;DR: Each time a user presses the space key, I want the next line of dialogue to appear.
Context: I've just started learning to code in the last few weeks (first basic html & css, now JS). I've mostly been using freecodecamp and YouTube. To help me learn more creatively, I thought I'd start making a little text-based game (BOTW-themed, because it's my favourite actual game). I have all sorts of ideas for things I'd like to implement later, but I'm a bit stuck early on.
The problem: At the beginning of the game, I want to have some lines of dialogue, that I'll .append into the document, each time the user presses the space key. The basic code looks like this:
$(document).keyup(function(e) {
if (e.which == 32) {
$('#gameText').append("<h2>It sounds familiar...</h2>");
}
});
$(document).keyup(function(e1) {
if (e1.which == 32) {
$('#zelda').append("<h3>Link...</h3>");
}
});
<script src="https://code.jquery.com/jquery-1.10.2.js"></script>
<h1> You hear an faint, incorporeal voice, carried by the wind... </h1>
<script>
function(e)
</script>
<h2 id="gameText"></h2>
<h3 id="zelda"></h3>
<p> Press <b>space</b> to continue</p>
The problem with that is that a single press of the space key will trigger all the .keyup events at once; whereas I want to bring the lines in one at a time.
I've tried a few different ideas, such as creating a number variable, and incrementing it on each keypress, then using a switch statement to select each line of dialogue.
let spacecount = 0;
while (spacecount < 10) {
$(document).keyup(function(e) {
if (e.which == 32) {
spacecount++;
}
});
switch (spacecount) {
case 1:
$('#gameText').append("<h2>It sounds familiar...</h2>");
break;
case 2:
$('#zelda').append("<h3>Link...</h3>");
break;
}
}
But it's just not happening, and I'm stumped. Apologies for the long-winded post.
This would be a more elegant solution. Instead of huge switch blocks you could have an array (or object) of dialogue lines and a counter to mark your next line.
const dialogue = [
["#gameText", "<h2>It sounds familiar...</h2>"],
["#zelda", "<h3>Link...</h3>"]
];
let counter = 0;
$(document).keyup(function(e) {
if (e.which == 32) {
if (counter >= dialogue.length)
return;
$(dialogue[counter][0]).append(dialogue[counter][1]);
counter++;
}
});
<div id="gameText"></div>
<div id="zelda"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
I think putting logic inside event listener should solve the problem:
let spacecount = 0;
$(document).keyup(function(e) {
if (spacecount < 10 && e.which == 32) {
switch (spacecount) {
case 1:
$('#gameText').append("<h2>It sounds familiar...</h2>");
break;
case 2:
$('#zelda').append("<h3>Link...</h3>");
break;
}
spacecount++;
}
});
You are using the same event for executing two functions. jQuery will execute both functions when the button is pressed. You need to set a counter and count the event.
Related
I am a noob to javascript and and programming really and I just want to know what I am doing wrong. Im sure this is a really simple question but I have no idea why this isn't working. According to research online I'm doing everything correctly.
var varname = 0;
$(document).keydown(function(e) {
if(e.which == 74) {
varname++;
console.log(varname);
}
}
Everytime I press "j" I want to increase my variable, but console log shows a consistent 1 and doesn't go any higher. What can I do Thanks for the help. The key press event works fine, the number just wont increase upon the keypress. Thanks again
you can just declare like this:
var varname = 0;
function keyPress(e){
if(e.which == 74) {
varname++;
console.log(varname);
}
}
In this case, your variable will keep it's previous value, and it will increment.
It's a little hard to tell, but I presume you're trying for something like this:
var jCounter = 0
document.getElementById('keycheck')
.addEventListener('keydown', function (evt) {
if (evt.which === 74) {
console.log("Yup, that's a 'j' alright.")
jCounter++
document.getElementById('jcounter').innerHTML = jCounter
}
})
<input type="text" id="keycheck" placeholder="I really like j's...">
<span id="jcounter">0</span>
I'm very new to JavaScript, and I'm currently trying to add a custom code to my Qualtrics survey that makes it so pressing the spacebar continues the survey in the "Text/Graphic" question type. I have a code that should be working; however, I'm getting an "Unexpected token (" error.
Here is the code:
Qualtrics.SurveyEngine.addOnload(function()
{
document.addEventListener("keydown", function(e) {
if (e.keyCode === 32) {
function(){
that.clickNextButton();
}
}
}
});`
I also found this answer to a similar question from a couple of years back:
Here is a simplified version that works (updated to hide NextButton):
Qualtrics.SurveyEngine.addOnload(function() {
$('NextButton').hide();
document.on("keydown", function(e) {
if (e.keyCode === 13) $('NextButton').click();
});
});
This code, however, doesn't work at all in my survey (as if it wasn't even there).
Any help is much appreciated, thanks in advance!
____ Edit _____
The code I have now used is the following:
Qualtrics.SurveyEngine.addOnload(function()
{
/*Place your JavaScript here to run when the page loads*/
});
Qualtrics.SurveyEngine.addOnReady(function()
{
/*Place your JavaScript here to run when the page is fully displayed*/
Qualtrics.SurveyEngine.addOnReady(function() {
$('NextButton').hide();
document.on("keydown", function(e) {
if (e.keyCode === 32) $('NextButton').click();
});
});
});
Qualtrics.SurveyEngine.addOnUnload(function()
{
/*Place your JavaScript here to run when the page is unloaded*/
});
The problem I have now is that the study autoadvances the next question whenever I press spacebar before ansewring a previous question.
Example
Question 1: Is the sentence you just saw a sensible continuation for the preceding sentence?
* participant presses space bar before answering the question with F for no and J for yes
* The study reminds the participant that they need to answer the question before proceeding to the next question
* Participant answers the question and the study automatically proceeds to the next question, because answering validates the question
--> the study only lets the participant see the next item for a second, and then autoadvances to the next item without the participant pressing any key.
The code I use for the F + J keys is the following:
Qualtrics.SurveyEngine.addOnload(function()
{
this.hideNextButton();
this.hidePreviousButton();
var that = this;
Event.observe(document, 'keydown', function keydownCallback(e) {
var choiceID = null;
switch (e.keyCode) {
case 74: // 'f' was pressed
choiceID = 2;
break;
case 70: // 'j' was pressed
choiceID = 1;
break;
}
if (choiceID) {
Event.stopObserving(document, 'keydown', keydownCallback);
that.setChoiceValue(choiceID, true);
that.clickNextButton();
}
});
});
I think it doesn't work due to a timing issue. Use addOnReady instead:
Qualtrics.SurveyEngine.addOnReady(function() {
$('NextButton').hide();
document.on("keydown", function(e) {
if (e.keyCode === 32) $('NextButton').click();
});
});
Note: with split screen preview mode you have to click in the window first or it won't recognize the key press.
EDIT:
I couldn't recreate your problem (your code worked as is for me when I tried it). However, try the following. It is cleaner and consistent. If it works be sure to accept the answer.
Space bar question:
Qualtrics.SurveyEngine.addOnReady(function() {
$('NextButton').hide();
if($('PreviousButton')) $('PreviousButton').hide();
var evt = document.on('keydown', function(e) {
if (e.which == 32) { //space bar pressed
evt.stop();
$('NextButton').click();
}
});
});
Yes/No question:
Qualtrics.SurveyEngine.addOnReady(function() {
$('NextButton').hide();
if($('PreviousButton')) $('PreviousButton').hide();
var that = this;
var evt = document.on('keydown', function(e) {
var choiceID = null;
if(e.which == 70) choiceID = 1; //'f' was pressed
else if(e.which == 74) choiceID = 2; //'j' was pressed
if (choiceID) {
evt.stop();
that.setChoiceValue(choiceID, true);
$('NextButton').click();
}
});
});
You need to remove the function() around that.clicknextbutton(), and change that to this. that doesn't make sense unless it is a variable set to the this keyword. The function(){} syntax is used to define an expression in a parameter.
Qualtrics.SurveyEngine.addOnload(function(){
document.addEventListener("keydown", function(e) {
if (e.keyCode === 32) {
this.clickNextButton();
}
});
});
I've been given some javascript code for recording keyboard presses in Qualtrics. Seems to work fine when I preview the survey, but as soon as I use the distribute survey link, it does not work at all.
I'm using this code for before the event I want to record 'x' keyboard presses for:
Qualtrics.SurveyEngine.addOnload(function()
{
Event.observe(document, 'keydown', function (e) {
switch (e.keyCode) {
case 88: // 'x' was pressed
var totalpresses = Qualtrics.SurveyEngine.getEmbeddedData("xhits");
if (totalpresses == "NaN"){totalpresses=1;}
totalpresses = parseInt(totalpresses);
totalpresses = totalpresses + 1;
Qualtrics.SurveyEngine.setEmbeddedData("xhits",totalpresses);
}
});
});
and i'm using this code for following the event:
Qualtrics.SurveyEngine.addOnload(function()
{
var totalpresses = Qualtrics.SurveyEngine.getEmbeddedData("xhits");
Qualtrics.SurveyEngine.setEmbeddedData("finalxhits", totalpresses);
which gives me 'xhits' for the section I need it for, but only when I preview the survey.
I am using embedded data in the survey flow to create 'xhits' and 'finalxhits', yet finalxhits doesn't seem to show a value either (not that this is the problem).
I am very new to javascript so would appreciate any help.
I'm not sure what is causing your issue (I haven't tried to recreate it), but try this:
Qualtrics.SurveyEngine.addOnload(function()
{
var totalpresses = parseInt("${e://Field/xhits}");
if (isNaN(totalpresses)) totalpresses = 0;
Event.observe(document, 'keydown', function (e) {
switch (e.keyCode) {
case 88: // 'x' was pressed
totalpresses = totalpresses + 1;
Qualtrics.SurveyEngine.setEmbeddedData("xhits",totalpresses);
}
});
});
Is that second piece of code attached to a subsequent question? I'm not sure what purpose it serves, but you can just do that assignment in the survey flow:
finalxhits = ${e://Field/xhits}
First of all, I'm new to Javascript. I would like to have an event repeat itself every time a user presses a key in Javascript. See the sample code below:
<script>
document.addEventListener('keydown', function(event){
if(event.keyCode == 39) {
document.write('Right was pressed');
}
})
</script>
When this code is run and the right arrow key is pressed, the statement is only printed once. I would like to have the event register multiple times, as many times as the user presses the key. Any suggestions?
The event is fired every time you press the key (and repeated if you hold the key down), but document.write() will every time override the content so it looks like nothing change, you could use innerHTML instead (just to see the effect) :
document.addEventListener('keydown', function(event){
if(event.keyCode == 39) {
//Not recommended as 'T.J. Crowder' mentioned in the comment
document.body.innerHTML += 'Right was pressed <br>';
}
})
You could use console.log() to debug and make sure the event was invoked :
document.addEventListener('keydown', function(event){
if(event.keyCode == 39) {
console.log('Right was pressed');
}
})
Actually it indeed triggered multiple times. The problem is document.write would clear the DOM.
This example works well for me.
script:
var counter = 0;
document.addEventListener('keydown', function(event){
if(event.keyCode == 39){
++counter;
document.getElementById("demo").innerHTML = "Key downed " + counter;
}
});
html:
<p id="demo">
</p>
I can't believe this hasn't been asked before (I searched and searched) but anyway.
How can I switch key events with pure JS?
For example, I want to switch the Enter button to mimic the Tab button. (I want to be able to push enter without submitting the form and instead switch fields to a Tab-like behavior e.i. switch form fields)
var enter = 13;
if (e.which === enter) {
// tabs to next field
getNextField(e.srcElement).focus();
// stops default enter
event.preventDefault();
event.stopPropagation();
}
implement getNextField() using .tabindex
function getNextField(obj) {
var next = obj.tabIndex + 1;
var all = document.getElementsByTagName("*");
for (var i in all) {
if (all[i].tabIndex === next) {
all[i].focus();
break;
}
}
}
This should give you a vague idea of how to do it. Flesh out the pseudocode yourself.