Goto somewhere based on a variable, JavaScript - javascript

Ok so I'm a kinda new to the whole JavaScript thing but I was just trying something Some kind of yes/no quiz thingy and I want to skip certain questions and stuff I came up with the following but the whole "continue Q + question_nr;" doesn't work like I hoped it would. How am I supposed to do this? :)
var question_nr = 1;
Q1:
function q1() {
var a1 = prompt("Wanna skip the next question?", "y/n");
switch(a1) {
case "y":
alert("k");
question_nr = question_nr + 2;
continue Q + question_nr;
break;
case "n":
alert("oki");
question_nr = question_nr + 1;
break;
default:
alert("please enter y or n.");
break;
}
}
Q2:
alert("test2");
//<insert question 2>
break;
Q3:
alert("test3");
//<insert question 3>
break;
<button onclick="q1()">test</button>
p.s. any good sites to help me learn JS are appreciated so I don't have to ask (probably really stupid) questions like this one in the future

I don't want to teach you, go to the code academy, but if you at least "don't know" how to implement something that works as you want, I can tell you how to do something that works somehow near how goto worked. Listen:
You can declare execution of your questions (let's call that "goto targets") as:
const QUESTIONS = {
Q1: function () {
someLogicThere();
},
Q2: function () {
someLogicThere();
}
};
And execute it in some way like this (this will throw an error if you don't define any of required questions):
switch(lastPrompt) {
case "y":
alert("k");
question_nr = question_nr + 2;
QUESTIONS["Q" + question_nr]();
break;
case "n":
alert("oki");
question_nr = question_nr + 1;
break;
default:
alert("please enter y or n.");
break;
}
}
But I assume that a bad code. You should wrap everything inside IIFE/module and use more html/angular/react to keep this organised.

I understand that you are still learning, but you should not use labels to do this. The following is a more simple way to accomplish this goal.
(function () {
var questions = [
'How much wood can a wood chuck chuck?',
'How many fish in the sea?',
'How does this JavaScript work?'
];
var index = -1;
window.askQuestion = function () {
var answer = prompt("Wanna skip the next question?", "y/n");
if(answer === 'y' || answer === 'n') {
index = (index + 1) + (answer === 'y');
if(questions[index]) {
alert(questions[index]);
} else {
alert("No more questions to ask.");
index = -1;
}
} else {
alert("please enter y or n.");
}
};
}());
A few things to note. The function above wraps its code in what is called a self-executing anonymous function. This makes it so that the variables declared inside it are within a private scope. Next, we store questions inside of an array while keeping in mind that the array index always begins at 0. This is why when we declare the variable for index that it begins at -1. If the answer given by the user is y or n, then we add one to the index plus true or false whether or not the answer is y. This conditionally increments index by 1 if n or 2 if y. Then check whether or not a question exists at the calculated index. If it does, trigger the alert for the question, or if not alert that there are no more questions and reset the index to -1.

Related

Using different array's with switch statements

I am creating a recycling app and am attempting to use a switch statement to provide the user with instructions on what to do with the item upon entering into an input field. I'm a little turned around on how to call it (I am very new to switch). Eventually I want to have a few different arrays according to material. How would I place the item's within an array in the a switch? Would I be better off with if else statements? Any advice would be much appreciated!
const plasticItem = ["Milk Jug , Shampoo, Deodarant, Soda Bottle"];
function recycleItem(plasticItem) {
let instructions = "";
switch (true) {
case plasticItem:
instructions = "Put in recycling";
break;
}
}
I made this code which should work:
function recycleItem(){
const x = document.querySelector("input").value;
switch(x) {
case "Milk Jug":
console.log("Milk");
break;
case "Shampoo":
// code block
console.log("Shampoo");
break;
case "Deodarant":
console.log("Deodarant");
break
case "Soda Bottle":
console.log("Soda Bottle");
break
default:
// code block
}
}

Why wont the randomization in this code work?

Thank you for answering my original question, and the reason i am simply editing this post for my second question about this code is because the site wont let me make very many questions. my question is why isnt makesjump1 randomly true or false? it always seems to come out true. please help #Yhlas and #codeConcussion
var isjumping1 = true;
while(isjumping1) {
var makesjump1 = Math.random()
if(makesjump1 => .51) {
makesjump1 = true }
else if(makesjump1 <= .50) {
makesjump1 = false }
var jump1 = prompt("Do you choose to JUMP, or let the fairies help you FLY").toUpperCase()
switch(jump1) {
case 'JUMP':
if(makesjump1 = true) {
console.log("You made the jump on your own, so the fairies reward you with a steel sword(9 DMG)")
damage = 9;
weapon = 'steel sword(9 DMG)'; }
else if(makesjump1 = false) {
console.log("You attempt the jump but miss it, and are hanging on by a thread")
console.log("The fairies rescue you, but you got scratched up, doing 3 damge to you.")
health = health - 3; }
isjumping1 = false;
break;
case 'FLY':
console.log("The fairies help you over the pit")
isjumping1 = false;
break;
default:
alert("That was not a choice!")
break; }
}
You're assigning it to true with every loop. Use == instead or just...
while(isjumping1)
while(isjumping1==1) - comparison
while(isjumping1=1) - assignment(always returns true)
The way that you're assigning the random value to makesjump1 is incorrect. It would fail if Math.random() returned a value in the range (0.50,0.51). Instead, try this:
var makesjump1 = Math.random()<0.5;

How to reduce "if statement" conditions? [reduce the conditions inside the if statement]

after days of hard thinking i choose to ask that question. I have if statement with multiple conditions:
//var current is array of arrays of integers
if((current[rot][0] + x)<blocks.length
&& (current[rot][1] + x)<blocks.length
&& (current[rot][2] + x)<blocks.length
&& (current[rot][3] + x)<blocks.length
&& !$(blocks[current[rot][0]+x]).hasClass("blockLand")
&& !$(blocks[current[rot][1]+x]).hasClass("blockLand")
&& !$(blocks[current[rot][2]+x]).hasClass("blockLand")
&& !$(blocks[current[rot][3]+x]).hasClass("blockLand"))
{
//something to happen here ONCE!
}
Because i want something inside to happen just once i think i cant use for loop.
So my question is: is there a possible way to reduce the conditions number? and how?
P.S.: Yes i figured out that i can use flag (true/false) inside and do my stuff outside this if, in another if - but i think that not always gonna work, because for every loop the flag will be different.
var b = true;
for (var i = 0; i <= 3; i++) {
// In two lines for being clear, but it's possible just in one
b = b && (current[rot][i] + x)<blocks.length
b = b && !$(blocks[current[rot][i]+x]).hasClass("blockLand");
// You could speed it up this way.
if(!b) break;
}
if (b) {
//something to happen here ONCE!
}
I think I understand what you are asking but let me know if there is anything else I can do.
JavaScript has a ternary (conditional operator) https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Conditional_Operator
This operator allows you to assign true/false values based on an internal if/else condition.
Here is some code for you to explain this...
window.onload = function() {
var one = 1;
var two = 2;
console.log(one > two ? "greater" : "not greater");
};
You can also use a Switch statement which you can read about here https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/switch.
Here is an example of a switch statement.
window.onload = function() {
var string = "testing this out";
switch (string) {
case "testing this out":
console.log('testing this out found in condition one');
break;
case "testing":
console.log('found testing');
break;
default:
console.log('not found');
break;
}
};
Let me know if I can improve this.

How to use a Math.random function in association with an IF statement

I am trying to output different messages based upon the output of a function that uses the math.random function to generate a number between 1 and 4.
function roll()
{
return Math.floor(Math.random()*4+1)
}
When a button is pressed the function is called and a global variable 'a' is assigned to the result of the roll function.
var a;
function buttonPressed() {
roll()
a = roll()
answertq = (x*y);
The following code essentially means that if the answer the user provides in the answer box is correct then depending upon the result of the roll function output a different message as below.
if (parseInt(document.getElementById("inputVal").value) == answertq)
{
if (a=1)
{
window.alert("Very good!");
}
else if (a=2)
{
window.alert("Excellent!");
}
else if (a=3)
{
window.alert("Correct, Nice work");
}
else if (a=4)
{
window.alert("Correct - Keep up the good work");
}
}
Except that when I do this I always get the first response ("Very good!") every time the question is correct. Meaning that there is something wrong with the roll function in that it keeps assigning 1 to the global variable 'a' or something else I have not spotted. Any help would be much appreciated. I have provided two screenshots of the problem below.
[1] http://imgur.com/riFktIH "Example One"
[2] http://imgur.com/YjcmuRx "Example Two"
Except that when I do this I always get the first response ("Very
good!") every time the question is correct.
The reason is because you are not comparing the values you are assigning. == is for comparison and = is for assignment.
Try this:
if (a==1)
{
window.alert("Very good!");
}
else if (a==2)
{
window.alert("Excellent!");
}
else if (a==3)
{
window.alert("Correct, Nice work");
}
else if (a==4)
{
window.alert("Correct - Keep up the good work");
}
You need to compare a==1 not assign a=1
Why don't you use an array for your messages?
That way you can use the random number as an index for the array.
var msg = [
"Very good!",
"Excellent!",
"Correct, Nice work",
"Correct - Keep up the good work"
];
function randomMsg (){
var random = Math.floor(Math.random() * 4);
alert(msg[random]);
}
edit: arrays are zero based so no "+1"
All of your if statements are using the assignment operator "=" not the comparison operator "==":
if (parseInt(document.getElementById("inputVal").value) == answertq) {
if (a==1) {
window.alert("Very good!");
}
etc...

Ways to improve performance of this javascript code?

Don't be frightened, its a very basic code.
Just wanted to check with you guys if you know any methods to make it faster ? (still learning)
It looks so ugly :)
Or, if you notice anything which could be made differently... Thanks!
function pic_form_function(form, nr, val) {
document.getElementById("image_to_delete").value=0;
var re = /\..+$/;
var extension = val.match(re);
if (extension==".jpg" || extension==".jpeg" || extension==".gif" || extension==".png" || extension==".bmp") {
if (nr==1){
var ID_file1 = document.getElementById("pic_id_nr1").value;
window.parent.document.getElementById("pic1_filename").value=ID_file1+extension;
window.parent.document.getElementById("annonsera_nr_pics").value=1;
window.parent.document.getElementById("iframe_upload_pic").style.height="180px";
document.getElementById("pic_target").style.height="160px";
document.getElementById("pic_target").style.display="block";
document.getElementById("remove_pic").value=0;
document.getElementById("extra_pic_checkbox").style.display="inline";
document.getElementById("extra_pic_fnt").style.display="inline";
}
else if (nr==2){
var ID_file2 = document.getElementById("pic_id_nr2").value;
window.parent.document.getElementById("pic2_filename").value=ID_file2+extension; //Passing fileInputName to parent window...
window.parent.document.getElementById("annonsera_nr_pics").value=2;
document.getElementById("extrapic").value=2;
document.getElementById("pic_file3").disabled=false;
}
else if (nr==3){
var ID_file3 = document.getElementById("pic_id_nr3").value;
window.parent.document.getElementById("annonsera_nr_pics").value=3;
window.parent.document.getElementById("pic3_filename").value=ID_file3+extension;
document.getElementById("extrapic").value=3;
document.getElementById("pic_file4").disabled=false;
}
else if (nr==4){
var ID_file4 = document.getElementById("pic_id_nr4").value;
window.parent.document.getElementById("annonsera_nr_pics").value=4;
window.parent.document.getElementById("pic4_filename").value=ID_file4+extension;
document.getElementById("extrapic").value=4;
document.getElementById("pic_file5").disabled=false;
}
else if (nr==5){
var ID_file5 = document.getElementById("pic_id_nr5").value;
window.parent.document.getElementById("annonsera_nr_pics").value=5;
window.parent.document.getElementById("pic5_filename").value=ID_file5+extension;
document.getElementById("extrapic").value=5;
}
}
if (extension!=".jpg" && extension!=".jpeg" && extension!=".gif" && extension!=".png" && extension!=".bmp") {
window.parent.document.getElementById("annonsera_imagenotvalid_error").style.display="block";
}
else {
window.parent.document.getElementById("annonsera_imagenotvalid_error").style.display="none";
form.submit();
}
}
If me, I will define following on the top.
$=function(x){return document.getElementById(x);}
will replace all the document.getElementById to $ first.
or better user jQuery.
About performance:
To extract the file extension you can use the String.substring method instead of a RegExp, the performance improvement would be negligible but I think it gains readability:
var extension = val.substring(val.lastIndexOf('.'));
About the code:
You could have only one ID_file variable declared at the top of your function, and use it in the if blocks.
The else if blocks where nr==2, 3, and 4 are really similar, and you could do the same for those three cases:
//..
else if (nr >= 2 && nr <= 4){
ID_file = document.getElementById("pic_id_nr"+nr).value; // point #1 assumed
window.parent.document.getElementById("pic"+nr+"_filename").value=ID_file+extension;
window.parent.document.getElementById("annonsera_nr_pics").value = nr;
document.getElementById("extrapic").value = nr;
document.getElementById("pic_file"+(+nr+1)).disabled=false;
}
About readability:
You could define shorthands to common and verbose function calls at the beginning as S.Mark also suggests:
var el = document.getElementById,
parentEl = window.parent.document.getElementById;
Continuing what CMS did with code repetition, you can refactor the common code outside the sequence of else if blocks.
The switch statement was made to replace a sequence of ifs.
Instead of the above two suggestions, you could define functions do to the same tasks for a more readable implementation.
If you continue to use regexps (I personally find them very readable), remember that match returns an array.
Also, the .+ will greedily match all characters after the first period. Better to only match non-periods with [^.]+.
Instead of the long sequence of string comparisons, you can use objects as associative arrays:
var imageExtensions = {'.jpg': 1, '.jpeg': 1, '.gif': 1, '.png': 1, '.bmp': 1};
if (imageExtensions[extension]) {
The last if ... else ... is unnecessary, considering that the condition checks for the negation of the condition in the first if. Just move the else block to the end of the first if and turn the last if (...) to an else.
Personally, I find short error handling code more readable when placed next to the if statement that detected the error, rather than after a long block handling the non-error case. After the previous refactor, let's swap the if block with the else block and negate the conditional.
Taking all the above together, we get:
function pic_form_function(form, nr, val) {
document.getElementById("image_to_delete").value=0;
var extension = val.match(/\.[^.]+$/);
if (extension) {
extension = extension[0];
}
var imageExtensions = {'.jpg': 1, '.jpeg': 1, '.gif': 1, '.png': 1, '.bmp': 1};
if (! imageExtensions[extension]) {
window.parent.document.getElementById("annonsera_imagenotvalid_error").style.display="block";
} else {
var ID_file = document.getElementById("pic_id_nr" + nr).value;
window.parent.document.getElementById("pic"+nr+"_filename").value=ID_file+extension;
window.parent.document.getElementById("annonsera_nr_pics").value=nr;
switch (nr) {
case 1:
window.parent.document.getElementById("iframe_upload_pic").style.height="180px";
document.getElementById("pic_target").style.height="160px";
document.getElementById("pic_target").style.display="block";
document.getElementById("remove_pic").value=0;
document.getElementById("extra_pic_checkbox").style.display="inline";
document.getElementById("extra_pic_fnt").style.display="inline";
break;
case 2: // FALLTHRU
case 3: // FALLTHRU
case 4:
document.getElementById("pic_file"+nr).disabled=false;
// FALLTHRU
case 5:
document.getElementById("extrapic").value=nr;
break;
}
window.parent.document.getElementById("annonsera_imagenotvalid_error").style.display="none";
form.submit();
}
}
which is shorter, but could be more readable.
Note that if the $ wrapper is defined in 'window.parent', you should be able to call it as window.parent.$ in the child:
window.parent.$("annonsera_imagenotvalid_error").style.display="none";
There isn't any special computation being done beside traversing elements and assigning their attributes some values. So the code is not performing much to try to improve its performance.
On the other hand, you should use a library like jQuery for the kind of work you are doing. You might be able to cut short many traversals because you can have jQuery reuse the object it found and continue further from this point to look for other objects...
You should cache your dom lookups e.g.
var pic_target = document.getElementById("pic_target");
You can then use this variable to to apply the style and it only does the dom lookup once. I think this is a key thing to speeding up the js

Categories