Loading indicator in promises - JS [duplicate] - javascript

I'm writing a game that lets 2 players take turns playing. After a player makes a viable move, the blank element covers the whole screen and a prompt would then appear to ask if they should proceed to the next turn. The blank element will be removed to show the game after OK is clicked on prompt.
However, the prompt would appear right after the viable move was made instead of after the style change. So the blank cover would never appear on screen if the user clicks OK. The only way for the style change to happen is if the user clicks cancel on the prompt.
Is there some way to make the prompt happen after a style change?
Just an example code
var nextTurn;
cover.style.visibility='hidden';
function displaySwitch(){
if(turn == 0){
cover.style.visibility='visible';
nextTurn = confirm("Click OK for next turn");
if(nextTurn == true){
cover.style.visibility='hidden';
turn++;
}
}else if(turn == 1){
cover.style.visibility='visible';
nextTurn = confirm("Click OK for next turn");
if(nextTurn == true){
cover.style.visibility='hidden';
turn--;
}
}
}

You could consider using setTimeout(() => { ... }). This allows the browser to do stuff (e.g. rendering) before continuing your code. Note that you might run into issues if you have code after a call to setTimeout, so you might have to change a lot of code. (For example, see MDN's docs for setTimeout.)
let nextTurn;
cover.style.visibility = 'hidden';
function displaySwitch() {
if(turn == 0) {
cover.style.visibility = 'visible';
setTimeout(() => {
nextTurn = prompt("Click OK for next turn");
if(nextTurn == true) {
cover.style.visibility = 'hidden';
turn++;
}
});
} else if(turn == 1) {
setTimeout(() => {
nextTurn = prompt("Click OK for next turn");
if(nextTurn == true) {
cover.style.visibility = 'hidden';
turn--;
}
});
}
}
...
setTimeout(displaySwitch, 0);
Note: if you need to support older browsers and aren't doing any pre-processing, replace () => { ... } with function() { ... } and let with var.

Use setTimeout with at least 50ms.
And you better use confirm instead of prompt because prompt returns an input value.
if (turn == 0) {
cover.style.visibility = 'visible';
setTimeout(function() {
nextTurn = confirm("Click OK for next turn");
if (nextTurn == true) {
cover.style.visibility = 'hidden';
turn++;
}
}, 50);
} else if (turn == 1) {
cover.style.visibility = 'visible'
setTimeout(function() {
nextTurn = confirm("Click OK for next turn");
if (nextTurn == true) {
cover.style.visibility = 'hidden';
turn--;
}
}, 50);
}

Related

Resetting "this.id" within a nested if statement

I have this function to control a memory game.
The user is presented by a serious of images, after some seconds the images disappear and then the user has to click on the images in a pre-decided order.
For instance the user first need to click on the image that represents a football, then a tree etc. If the user fails at anytime the game is over.
The problem now is that I can't reach the second nested if-statement. This.id is stuck to the first image clicked, is there a way to reset this.id so that the user can click a second image? Or other solutions?
function flagsAddEventlistener() {
if (this.id == correctOrderArray[0]) {
points += 1;
userMessageElement.innerHTML = "Correct answer";
this.src = `flags/${correctOrderArray[0]}.png`;
if (this.id == correctOrderArray[1]) {
points += 1;
userMessageElement.innerHTML = "Correct answer";
this.src = `flags/${correctOrderArray[1]}.png`;
}
} else {
userMessageElement.innerHTML = "Faulty answer";
}
}
Since you need to know how many times a user clicked on the image, you need to add a state (a variable defined outside your listener).
Here is a simple example:
let counter = 0;
function flagsAddEventlistener() {
if (this.id == correctOrderArray[counter]) {
points++;
userMessageElement.innerHTML = "Correct answer";
this.src = `flags/${correctOrderArray[counter]}.png`;
} else {
userMessageElement.innerHTML = "Faulty answer";
}
counter++;
}

How to disable onkeyup for a few seconds

im creating a browser game and i have added keybinds so the player can use keys to move around the world.
If people use the buttons to move, these buttons are getting hidden for 5 seconds to allow an animation to end. Now i want to do this for the keybinds too.
For example: Player presses spacebar and a interval will run that lasts 5 seconds. Pressing space again will glitch out really bad running the same interval twice. So how do i disable a function for 5 seconds after it has been called so that it won't glitch out?
This is the code i use for the keys:
<script>
document.body.onkeyup = function(e){
if(e.keyCode == 32){
var cmd = "<?php echo $row['HEADING']; ?>";
if(cmd == "N") myMoveUp();
if(cmd == "E") myMoveRight();
if(cmd == "S") myMoveDown();
if(cmd == "W") myMoveLeft();
}
if(e.keyCode == 37){
ChangeHeadingKP("W");
}
if(e.keyCode == 38){
ChangeHeadingKP("N");
}
if(e.keyCode == 39){
ChangeHeadingKP("E");
}
if(e.keyCode == 40){
ChangeHeadingKP("S");
}
}
</script>
Any help would be appreciated.
I wouldn't rely on timing (say, 5 seconds) because when you change them, you'll have to review your code.
Instead I'd rely on toggling a flag by calling specific methods, like this:
keymanager.suspend();
// play animation, cutscene or whatever
keymanager.resume();
Those two functions are easy to define, along with the keymanager, as follows:
var keymanager = {
"active": true,
"suspend": () => {
keymanager.active = false;
},
"resume": () => {
keymanager.active = true;
}
};
All that remains is the key event handler bailing out when keys are deactivated:
document.body.onkeyup = function (e) {
if (!keymanager.active)
{
return; // do not process any keys
}
// rest of your code...
}

How to make a keyboard button not get spammed in javascript. (Making a delay)

I was working on Babylon.js when I wanted to make a jump. I found a website and copied it jump code and it works perfectly! But I want to make a real game and I don't want people spamming spacebar to go flying. How could I make it have a few second delay so no one can keep on spamming spacebar and go flying?
function jump(){
camera.cameraDirection.y = 2;
}
document.body.onkeyup = function(e){
if(e.keyCode == 32){
//your code
console.log("jump");
setTimeout(jump(), 1000);
}
}
Link to my game
https://playground.babylonjs.com/#JCE1G3
One option would be to create a persistent boolean variable such as justJumped, and only jump if justJumped is false. When jumping, set justJumped to true, and create a timeout that resets it back to false after the duration of the jump, which looks to be a bit less than half a second:
let justJumped = false;
document.body.onkeyup = function(e) {
if (e.keyCode == 32 && !justJumped) {
justJumped = true;
setTimeout(() => justJumped = false, 400)
console.log("jump");
jump();
}
}
Also note that setTimeout(jump(), 1000); probably isn't doing what you're thinking it does - it invokes jump immediately. If you wanted to call the jump function after 1000ms, just pass the function name itself:
let justJumped = false;
document.body.onkeyup = function(e) {
if (e.keyCode == 32 && !justJumped) {
justJumped = true;
setTimeout(() => justJumped = false, 1400)
console.log("jump");
setTimeout(jump, 1000);
}
}
You can also use other library to achieve it. My favorite one is lodash. You can use _.throttle
var throttled = _.throttle(jump, 1000);
document.body.onkeyup = function(e) {
if (e.keyCode == 32) {
throttled()
}
}
if you don't want to jump immediately after the first key up. you can add option trailing: false
var throttled = _.throttle(jump, 1000, { 'trailing': false });

combine checkbox alert function with detect function

the goal here is to detect if a user is checking out on my site and then prompt them with a special alert if they uncheck a box.
how do i combine to two functions to do this?
the detect function so far is this
var pathArray = window.location.pathname.split('/');
if (pathArray.length >= 3) {
if (pathArray[1].toLowerCase() == "commerce") {
var page = pathArray[2].toLowerCase();
if (page.indexOf("show-cart") == 0) {
console.log("Detected the cart page."); // This works
} else if (page.indexOf("checkout") == 0) {
console.log("Detected the checkout page."); // Does not work (no injection)
} else if (page.indexOf("order-confirmed") == 0) {
console.log("Detected the order confirmation page."); // Does not work (no injection)
}
}
}
and the checkbox alert function is this:
function validate() {
var checkoutHistory = document.getElementById('shipToBilling');
if (checkoutHistory.checked) {
} else {
alert("You have elected to turn off checkout history.");
}
}
window.addEventListener("load", validate, false);
Your onclick function can call both your functions

Javascript seems not working to load image when page loads

I'm using Javascript to make my checkboxes larger. Doing this I use image one for black checkbox and another one with the checked checkbox. It works like the real checkbox. However, when the page loads, the black checkboxes are not successfully loaded unless I click somewhere in the page to invoke them. Please check here to the page.
Belowing is my js code which I think it will impact this:
var Custom = {
init: function() {
var inputs = document.getElementsByTagName("input"), span = Array(), textnode, option, active;
for(a = 0; a < inputs.length; a++) {
if((inputs[a].type == "checkbox" || inputs[a].type == "radio") && inputs[a].className == "styled") {
span[a] = document.createElement("span");
span[a].className = inputs[a].type;
if(inputs[a].checked == true) {
if(inputs[a].type == "checkbox") {
span[a].style.background = unchecked;
} else {
span[a].style.background = unchecked;
}
}
inputs[a].parentNode.insertBefore(span[a], inputs[a]);
inputs[a].onchange = Custom.clear;
if(!inputs[a].getAttribute("disabled")) {
span[a].onmousedown = Custom.pushed;
span[a].onmouseup = Custom.check;
} else {
span[a].className = span[a].className += " disabled";
}
}
}
}
Below is my image on form load:
And this is my page when clicking on anywhere:
Which other functions and variables are already defined. Thus could anyone help me to enable them to display whenever the form loads?
I don't known why you use that
if(inputs[a].checked == true) {
if(inputs[a].type == "checkbox") {
span[a].style.background = unchecked;
} else {
span[a].style.background = unchecked;
}
}
But when I open your script in http://checkintonight.freeiz.com/js/custom-form-elements.js
Try to call function clear() in end of Custom.init(), it works
init: function() {
//
...
//
this.clear();
}
Sorry for my bad English
Eventually, I found a bug in my Javascript code. I add the else statement in the init() function to test if the checkbox is also not checked. So the code becomes like below:
if(inputs[a].checked == true) {
if(inputs[a].type == "checkbox") {
span[a].style.background = unchecked;
}
} else {
span[a].style.background = unchecked;
}
Then it works! Thanks everyone that reviewed and answered to my question.

Categories