How do I call a random function on button click? - javascript

Here is a quick background on project goals: I'm trying to build a simple math game that provides random math problems when you click on a button. Later, I'll figure out a way to check whether the answers are correct. I started this process by creating an input form.
I'm trying to call a random function in a javascript array using a button in HTML. The button calls a random function that is decided when I refresh the page. Once I refresh the page, the a function is randomly selected and the button continues to give the results of that function over and over. The button only calls a different function if I refresh the page.
I would prefer to have the button call a random function in my array each time the button is clicked. Anybody know how I could achieve this?
Here's my code:
const btn = document.querySelector('#START')
const randomFunc = [
multiplication,
division,
addition,
subtraction,
]
btn.addEventListener(
'click', randomFunc[Math.floor(Math.random() * randomFunc.length)]
)
function multiplication(params) {
let num1 = Math.floor(Math.random() * 13);
let num2 = Math.floor(Math.random() * 13);
let problemResult = num1 * num2;
console.log(num1, '*', num2, '=', problemResult);
document.getElementById('mathProblem').innerHTML = (`${num1} * ${num2} =`);
}
function division(params) {
let num1 = Math.floor(Math.random() * 13);
let num2 = Math.floor(Math.random() * 12) + 1;
let problemResult = (num2 * num1) / num2;
console.log(num1, '/', num2, '=', problemResult);
document.getElementById('mathProblem').innerHTML = (`${num1} / ${num2} =`);
}
function addition(params) {
let num1 = Math.floor(Math.random() * 13);
let num2 = Math.floor(Math.random() * 13);
let problemResult = num1 + num2;
console.log(num1, '+', num2, '=', problemResult);
document.getElementById('mathProblem').innerHTML = (`${num1} + ${num2} =`);
}
function subtraction(params) {
let num1 = Math.floor(Math.random() * 13);
let num2 = Math.floor(Math.random() * 13);
let numList = [num1, num2];
numList.sort(function(a, b) {
return b - a
});
let problemResult = numList[0] - numList[1];
console.log(numList[0], '-', numList[1], '=', problemResult);
document.getElementById('mathProblem').innerHTML =
(`${numList[0]} - ${numList[1]} =`);
}
<div>
<button type="button" class="btn btn-primary btn-lg" id="START">Press here for your first problem</button>
<script src={% static 'js/game_logic.js' %}></script>
<p id="mathProblem">Your problem will appear here</p>
<form action="">
<input type="text" placeholder="Type your answer here">
</form>
</div>

Wrap it in another function that selects a random function each time the click happens.
Also, your functions don't use params, so it's not needed.
const btn = document.querySelector('#START')
const randomFunc = [
multiplication,
division,
addition,
subtraction,
]
btn.addEventListener(
'click',
function() {
randomFunc[Math.floor(Math.random() * randomFunc.length)]();
}
)
function multiplication() {
let num1 = Math.floor(Math.random() * 13);
let num2 = Math.floor(Math.random() * 13);
let problemResult = num1 * num2;
console.log(num1, '*', num2, '=', problemResult);
document.getElementById('mathProblem').innerHTML = (`${num1} * ${num2} =`);
}
function division() {
let num1 = Math.floor(Math.random() * 13);
let num2 = Math.floor(Math.random() * 12) + 1;
let problemResult = (num2 * num1) / num2;
console.log(num1, '/', num2, '=', problemResult);
document.getElementById('mathProblem').innerHTML = (`${num1} / ${num2} =`);
}
function addition() {
let num1 = Math.floor(Math.random() * 13);
let num2 = Math.floor(Math.random() * 13);
let problemResult = num1 + num2;
console.log(num1, '+', num2, '=', problemResult);
document.getElementById('mathProblem').innerHTML = (`${num1} + ${num2} =`);
}
function subtraction() {
let num1 = Math.floor(Math.random() * 13);
let num2 = Math.floor(Math.random() * 13);
let numList = [num1, num2];
numList.sort(function(a, b) {
return b - a
});
let problemResult = numList[0] - numList[1];
console.log(numList[0], '-', numList[1], '=', problemResult);
document.getElementById('mathProblem').innerHTML =
(`${numList[0]} - ${numList[1]} =`);
}
<div>
<button type="button" class="btn btn-primary btn-lg" id="START">Press here for your first problem</button>
<script src={% static 'js/game_logic.js' %}></script>
<p id="mathProblem">Your problem will appear here</p>
<form action="">
<input type="text" placeholder="Type your answer here">
</form>
</div>

Your code of:
randomFunc[Math.floor(Math.random() * randomFunc.length)]
is not stored inside of a function, so as soon as the page loads and the script is initially parsed, that statement is executed and your random function name is retrieved from the array and that code will be replaced with whichever function name was gotten, so for the rest of that page's use, the code will actually be static and be evaluated like this:
// showing multiplication here, but will be whichever random name was initially returned
btn.addEventListener('click', multiplication)
But, once it's gotten, the initial randomizing code won't be executed again, because it will have already been replaced by the result of the first pass through parsing the script. So, in the end, you get one call for a random function reference and that result is what you stick with until the page is reloaded.
What you need is for that randomizing code to be executed every time the button is clicked, so by wrapping it in another function (which localizes the statement), that will happen:
btn.addEventListener(
'click', function() { randomFunc[Math.floor(Math.random() * randomFunc.length)](); }
)
Now, every time you click the button, randomFunc[Math.floor(Math.random() * randomFunc.length)] will get a new function name and () after it will cause it to be invoked because the whole expression is inside of an anonymous function expression, which will become the event handler.

it's because you're already generated a function and assigned it here
btn.addEventListener(
'click', randomFunc[Math.floor(Math.random() * randomFunc.length)]
)
in order to randomize it you have to make a callback that generates a random function instead
btn.addEventListener(
'click', function() {
const a = randomFunc[Math.floor(Math.random() * randomFunc.length)];
a();
}
)
it should now work. https://jsbin.com/duyosiluna/edit?html,js,console,output

Wrap with another function so that it gets executed on each click
btn.addEventListener('click', function () {
randomFunc[Math.floor(Math.random() * randomFunc.length)]()
})
Your code set the random function only once (on page Load) so it's always the same when clicking the button
btn.addEventListener('click', randomFunc[Math.floor(Math.random() * randomFunc.length)])

Have you tried using a arrow function, like so
btn.addEventListener(
'click', () => randomFunc[Math.floor(Math.random() * randomFunc.length)];
)
This will also execute the function on each click

The function addEventListener() adds one function to an HTML-Element when executed.
This means, when your addEventListener()-line is executed (which it only is once, when your script is executed for the first time), it selects one of your functions and adds only that.
To be able to select one of you functions repeatedly on click, you would need to instead add a function that selects on of yours, instead of adding one of yours directly. That way, the "selection"-function runs every time your button is clicked.
Here is an example:
var funcToSelect = [func1, func2, func3];
document.querySelector('button').addEventListener('click', () => {
funcToSelect[Math.floor(Math.random() * funcToSelect.length)]();
});
function func1() {
console.log('First output');
}
function func2() {
console.log('Output from second');
}
function func3() {
console.log('Yet a third output');
}
<button>Run a random function!</button>

Related

Why can I only change the CSS style through JS only once?

Just start to learn JS. I wanna change the fontSize randomly every time I click the button, but it only work the first time I click.
var oBox = document.querySelector('#box');
var randomNumber = ((Math.random() * 10) * 10).toString();
var b = document.querySelector('#button');
b.addEventListener('click', function () {
oBox.style.fontSize = randomNumber + 'px';
})
The line var randomNumber = ((Math.random() * 10) * 10).toString(); is executed only once. Therefore, you should use a constant: const randomNumber = ((Math.random() * 10) * 10).toString();.
In your case you have to move this line inside the function. After that, the line will be executed after every click event:
const box = document.querySelector('#box');
const button = document.querySelector('#button');
button.addEventListener('click', function () {
const randomNumber = ((Math.random() * 10) * 10).toString();
box.style.fontSize = randomNumber + 'px';
});
<div id="box">Hello World</div>
<button id="button">Button</button>
You should also give your JavaScript variables meaningful names. Just b is not a good name for more complex software. Also take a look in the documentation for the difference between let, var, and const.
Because you are only generating the random number once. You need to either make a function to generate a different random number every time it's called, like this:
var oBox = document.querySelector('#box');
var b = document.querySelector('#button');
function getRandomNumber() {
return ((Math.random() * 10) * 10).toString();
}
b.addEventListener('click', function () {
oBox.style.fontSize = getRandomNumber() + 'px';
})
<div id="box">
This is a test
</div>
<button id="button">
Button
</button>
Or to generate it directly in the click event, like this:
var oBox = document.querySelector('#box');
var b = document.querySelector('#button');
b.addEventListener('click', function () {
const randomNumber = ((Math.random() * 10) * 10).toString();
oBox.style.fontSize = randomNumber + 'px';
})
<div id="box">
This is a test
</div>
<button id="button">
Button
</button>

Looking to add a random number to html element? [duplicate]

Need help with Javascript to generate number in HTML. I'm close but can't get it to quite work. Help would be appreciated.
http://jsfiddle.net/xmPgR/251/
function getNumber() {
var minNumber = 0; // The minimum number you want
var maxNumber = 100; // The maximum number you want
var randomnumber = Math.floor(Math.random() * (maxNumber + 1) + minNumber); // Generates random number
$('#myNumber').html(randomnumber); // Sets content of <div> to number
return false; // Returns false just to tidy everything up
}
window.onload = getNumber; // Runs the function on click
document.getElementById("yourNumber").innerHTML = randomnumber;
<div id="myNumber"></div>
<p id="yourNumber">
</p>
Your onload works after the next statement, because it works asynchronously. And besides this, you use a randomnumber outside from it's scope, where it is not accessible.
So I suggest you to return the randomnumber from the function and use that function in the onload event handler. Inside that handler call your function, get the number and assign to your element's text.
And also if your getNumer's logic is to return the number, don't assign anything inside it, just return the number. It's responsibility is to return a random number. Pass the range to it, don't hard code: in another place you can need a random number in the different range. Other logic implement outside of that function.
function getRandomNumber(minRange, maxRange) {
return Math.floor(Math.random() * (maxRange + 1) + minRange);
}
window.onload = function() {
const rand = getRandomNumber(0, 100);
document.getElementById("yourNumber").innerHTML = rand;
$('#myNumber').html(rand);
};
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="myNumber"></div>
<p id="yourNumber"></p>
Here you go:
function getNumber() {
var minNumber = 0; // The minimum number you want
var maxNumber = 100; // The maximum number you want
var randomnumber = Math.floor(Math.random() * (maxNumber + 1) + minNumber); // Generates random number
document.getElementById("myNumber").innerHTML = randomnumber; // Sets content of <div> to number
return false; // Returns false just to tidy everything up
}
window.onload = getNumber; // Runs the function on click
<div id="myNumber"></div>
<p id="yourNumber">
</p>

JavaScript save sum to field

New to JavaScript.
I have a form with three fields, quantity, amount (hidden), sum.
The user enters the quantity they would like to buy and its multiplied with amount and shows the total in sum. If the user change the amount the sum changes. What I cant solve is how to save the sum in the field, when the user use checkout the sum fields ends up empty.
The script:
function getElementByName(name) {
const elements = document.getElementsByName(name)
if (elements.length !== 1) {
throw new Error('multiple elements found with name ' + name)
}
return elements[0]
}
/**
* Calculate sum
*/
function calculateSum() {
const num1 = getElementByName('quantity').value;
const num2 = getElementByName('amount').value;
getElementByName("sum").value = num1 * num2;
}
/**
* Listen to events
*/
function listenToEvents() {
const elem = getElementByName('quantity')
elem.addEventListener('keyup', () => {
calculateSum()
})
}
listenToEvents()
You do not need the event handler function inside a function. I will also suggest you to use input event instead of keyup. You can also attach the event on both quantity and amount.
Demo:
function getElementByName(name) {
const elements = document.getElementsByName(name)
if (elements.length !== 1) {
throw new Error('multiple elements found with name ' + name)
}
return elements[0]
}
/**
* Calculate sum
*/
function calculateSum() {
const num1 = getElementByName('quantity').value;
const num2 = getElementByName('amount').value;
getElementByName("sum").value = num1 * num2;
}
/**
* Listen to events
*/
const elems = [getElementByName('quantity'),getElementByName('amount')]
elems.forEach(function(el){
el.addEventListener('input', () => {
calculateSum()
});
});
Quantity: <input type="number" name="quantity"/><br><br>
Amount: <input type="number" name="amount"/><br><br>
Sum: <input name="sum"/>

typescript - calling function at random intervals in ionic

I would like to repeatedly call the changeStyle() function at random intervals
here is my code so far:
this.platform.ready().then(() => {
this.myFunction()
});
myFunction() {
var min = 5,
max = 10;
var rand = Math.floor(Math.random() * (max - min + 1) + min); //Generate Random number between 5 - 10
this.changeStyle()
setTimeout(this.myFunction, rand * 1000);
}
changeStyle() {
console.log('changing style');
this.sensorImage = 'path/to/image1';
setTimeout(() => {
this.sensorImage = 'path/to/image2';
},
2000);
}
the relevant html code is
<img id='35' (click)="changeStyle()"
src="{{sensorImage}}">
ideally what this should do is call the changeStyle() function repeatedly and randomly without any input from me. however, I get a runtime error saying:
'TypeError: this.changeStyle is not a function. (In 'this.changeStyle('')', 'this.changeStyle' is undefined)'
Can you update your setTimeout(this.myFunction, rand * 1000); function to,
setTimeout(this.myFunction.bind(this), rand * 1000);
I believe the issue is related to this context.
You could do something like this,
changeStyle() {
...
...
const randomMilliSeconds = Math.floor( Math.random() * 10 ) * 1000;
setTimeout(() => {
this.changeStyle();
}, randomMilliSeconds)
}
You just need to call changeStyle once, manually or using click event and it will call itself at random intervals.

Howto run function every few seconds that has return values?

How can I run this every few second , without blocking the rest of the pagefrom loading.
function Create() {
var SomeArray = [];
for ( var i=0; i<=1 ; i ++) {
SomeArray[i] = (Math.random() * 10) + 1;
//alert(arr[0]);
}
return SomeArray;
}
var x = Create();
alert(x[0] + x[1]);
I was trying this var timer = setInterval(Create, 5000); it prevent loading rest of the page.
i want to get new values every few seconds
A basic example would be:
var counter = 0;
var timerRef;
var increment = function() {
counter += 1;
console.log(counter);
timerRef = setTimeout(increment, 1000);
}
setTimeout(increment, 1000);
// clearTimeout(timerRef);
Please avoid document.write refer the screencast for further details.
setInterval() can be configured to repeatedly call any function you designate at whatever time interval you request. But, you can't retrieve a return value from that function. Instead, you need to process the results from within the callback that you pass to setInterval() or call some other function and pass the results you generate inside the callback. This is how asynchronous functions work in JavaScript. I've provided several examples below of your options:
If you just want to generate two random decimal values between 1 and 10 (inclusive) every 5 seconds, you can do that like this:
var interval = setInterval(function() {
var rand1 = (Math.random() * 10) + 1;
var rand2 = (Math.random() * 10) + 1;
// now insert code here to do something with the two random numbers
}, 5000);
If you wanted the random values to be integers (which is more common), then you would do this:
var interval = setInterval(function() {
var rand1 = Math.floor(Math.random() * 10) + 1;
var rand2 = Math.floor(Math.random() * 10) + 1;
// now insert code here to do something with the two random numbers
}, 5000);
If you want to call a function and pass it those two random numbers, you can do this:
function processRandoms(r1, r2) {
// code here to do something with the two random numbers
}
var interval = setInterval(function() {
var rand1 = Math.floor(Math.random() * 10) + 1;
var rand2 = Math.floor(Math.random() * 10) + 1;
processRandoms(rand1, rand2);
}, 5000);
You can then stop the recurring interval at any time with this:
clearInterval(interval);

Categories

Resources