I have a basic javascript/html boardgame to be played by two players on one screen. When player1 finishes their turn, I want their board to be hidden, and an alert to pop up asking player2 if they are ready to take their turn. Then player2's board becomes visible. I have tried a bunch of things and can't get it to work.
var hide = false;
displayBoard(player1);
function displayBoard(player){
for (i = 0; i < boardSize + 1; i++) {
for (j = 0; j < boardSize + 1; j++) {
var gameSquare = document.createElement("div");
var squareText = document.createElement("span");
squareText.textContent = boardArray[j][i];
if(hide){
gameSquare.style.visibility = 'hidden';
squareText.style.visibility = 'hidden';
}
gameSquare.appendChild(squareText)
boardContainer.appendChild(gameSquare);
var topPosition = j * squareSize;
var leftPosition = i * squareSize;
gameSquare.style.top = topPosition + 'px';
gameSquare.style.left = leftPosition + 'px';
}
}
function fire(){ //This happens when a player clicks on the board
event = event || window.event;
var source = event.target || event.srcElement;
//a bunch of game logic, changing up arrays
//end of player's turn
hide = true; //I want to hide the board until the next player starts
displayBoard(thisPlayer); //To update the board being hidden
window.alert("press okay to begin " + nextPlayer + "'s turn");
hide = false;
displayBoard(nextPlayer);
}
When I do this, the visibility doesn't change in the html DOM.
I have also tried setting the visibility to hidden in the fire() function, which didn't work. I've tried setting all children of the boardContainer to hidden. I've tried doing all of these before, during, and after the bulk of the displayBoard function. I've tried disabling the cache. I've tried setting display to none. I've tried adding waiting periods after displayBoard().
What is the correct way to do this?
I'm also not allowed to use JQuery for this FYI.
Edit: instead of iterating through the elements I added this to the beginning of displayBoard():
if (hide){
boardContainer.style.visibility = "hidden";
opposingBoardContainer.style.visibility = "hidden";
} else{
boardContainer.style.visibility = "visible";
opposingBoardContainer.style.visibility = "visible";
}
The result of this is that if I eliminate the else block, the board disappears after the end of the first turn. If I leave the else block in, no change seems to happen. So I suspect that it is disappearing and coming back too quickly for me to tell instead of disappearing and waiting for the alert window like I want it to. Any thoughts?
The result of this is that if I eliminate the else block, the board disappears after the end of the first turn. If I leave the else block in, no change seems to happen. So I suspect that it is disappearing and coming back too quickly for me to tell instead of disappearing and waiting for the alert window like I want it to. Any thoughts?
hide = true; //I want to hide the board until the next player starts
displayBoard(thisPlayer); //To update the board being hidden
window.alert("press okay to begin " + nextPlayer + "'s turn");
hide = false;
displayBoard(nextPlayer);
So basically what is going on here is when you call alert the DOM has not yet rendered again, so your board is still there when the alert fires and blocks the rest of the code from executing.
So when you click okay two things may be happening.
It renders the board invisible and then executes displayBoard which renders it visible immediately again.
It executes displayBoard again before rendering and then when it next renders it will be visible so nothing happens.
Either way you are going to need to change the way you handle turns so that it doesn't rely on alert to block execution.
Related
I am tweaking the code of a chrome extension to display the content of a page element in the tab title and scroll it fir navigating open ticket tabs easer. As below
// Need to change this, mousemove listener is super harsh on resource
document.addEventListener("mousemove", function() {
// call the banner element
let bannerTextElements = document.getElementsByClassName("cw_BannerView");
// console.log(bannerTextElements);
// console.log(bannerTextElements[0]);
if (bannerTextElements[0]) {
// console.log("ok");
// console.log(bannerTextElements[0].innerHTML);
// Find and get ticket detail
let bannerTextLine = bannerTextElements[0].getElementsByClassName("detailLabel");
// console.log(bannerTextLine);
if (bannerTextLine[0]) {
// console.log(bannerTextLine[0].innerHTML);
// Trim "Service Ticket for cleanness Need to do this for 'Manage' too"
let tickettext = bannerTextLine[0].innerHTML.split("Manage ");
let tickettext1 = bannerTextLine[0].innerHTML.split("Service Ticket ");
// console.log(tickettext[0]);
// console.log(tickettext[1]);
// Set the title equal to everything after "Service Ticket"
if (tickettext1[1]) {
document.title = tickettext1[1];
// now works!! bit clunky though
var documentTitle = tickettext1 + " - ";
(function titleMarquee() {
document.title = documentTitle = documentTitle.substring(1) +
documentTitle.substring(0,1);
setTimeout(titleMarquee, 160);
})();
} else {
// For everything else, just display what's already there
document.title = tickettext1[0];
}
}
}
}, false);
(ignore the appalling indents i promise thats just on this post! )
However, due to the slow page load the only eventlistener i can get to pick the content of the banner text is 'mousemove' which naturally has the negative side effects of A. Firing infinite times as you view the page and also resetting the scroll to the start as you mouse over.
document.OnLoad and window.onload just stops this working and it loads the default tab title
Is there a way to get onLoad to run after an arbitrary delay, say 10s or to check to make sure that the classname cw_bannerview is loaded up and populate with the ticket title?
<script src = "http://code.jquery.com/jquery-1.10.2.min.js"></script>
<script>
$(document).ready(function(){
var secs_time;
var timer2;
var arrayseq1 = [];
var secs_up = 0;
var timer1;
var secs_down = 0;
$("#pad").mousedown(function(){
$(this).css("background-color", "lightgrey");
clearInterval(timer2);
timer1 = setInterval(function(){
secs_down = secs_down + 1;
$("#pad").html(secs_down);
},1);
arrayseq1 = arrayseq1.concat([secs_down]);
}).mouseup(function(){
$(this).css("background-color", "grey");
clearInterval(timer1);
timer2 = setInterval(function(){
secs_up = secs_up + 1;
$("#pad").html(secs_up);
},1);
arrayseq1 = arrayseq1.concat([secs_up]);
});
$("#pad").mouseleave(function(){
clearInterval(timer2);
});
$("#done").click(function(){
arrayseq1.splice(1, 1);
arrayseq1.splice(0, 1);
var counter = 0;
var colors = ["#FF3E96", "#4169E1", "#7FFF00","#FF4500","#FF7F00", "black", "white"];
while(counter <= arrayseq1.length){
setTimeout(function(){
var color = colors[Math.floor(Math.random()*colors.length)];
$("body").css("background-color", color);
}, arrayseq1[counter]);
counter++;
}
});
});
</script>
<div style = "height:500px;width:600px;background-color:grey;border-radius:4px;margin:0 auto;margin-top:10%;" id = "pad"></div>
<input type = "button" id = "done" value = "play">
Hi all.
I am making a small program, that when you press, and press of a huge grey button, it records the time its held down, and up and all put into an array (read the code to get a better understanding, its not to hard to understand). Anyway, so it records the times to the array successfully, so the array "arrayseq1" does have a list of times e.g [106,144,114,152,122,161,130,311,148,357]. The problem comes when i try and loop through each number, and use each as a delay for the flash of the background. So, the specific problem is when i substitute "arrayseq1[counter]" in the setTimeout function. For some reason i do not understand, it is undefined. Why? How can i fix this?
in this jsfiddle: http://jsfiddle.net/5V4Lv/
I alert the value arrayseq1[counter] the line before i use it for the setTimeout function, and as you will see, it alerts "undefined"
so you can test this out successfully, click on the grey box fastly and randomly, and then when you are down, move your mouse off the box to stop recording. Then click play to start the flashing.
The original aim of this was for the background to flash in random colours in exact sync and beat to how you initially clicked the grey box.
Thanks!
I have a site that has an image gallery that changes images every few seconds using JavaScript; however, I want to know how to STOP the images from changing when a user clicks on one of the images.
So far, the images are rotating as planned, but I can't seem to get the "onClick" scripting to STOP the rotation when the user clicks on an image. I don't need to have an alert popup or need it to do anything, I just need it to STOP the image rotation when someone clicks on one of the pictures.
Here's the HTML code I have:
else (getValue=='STOP')
{
alert("STOPPED");
}
That won't do what you probably want it to do. It should be:
else if (getValue=='STOP')
{
alert("STOPPED");
}
First of all, you missed out on the keyword "IF" in one of the lines of your code.
However, the way to create a terminable repetitive action is to setInterval and then use clearInterval to terminate the repetition.
semaphore = setInterval(somefunction, someinterval);
clearInterval(semaphore);
Example (I wrote this off-the-cuff, so there might be some errors, but you shd get the idea):
<img src="./images/image1.jpg" id="imageGallery" name="imageGallery"
onclick="chooseImg(this)" />
<script>
var turn = setInterval(function(){imgTurn()},5000);
var images = function2CreateImgArray();
var imageN = 0;
function chooseImg(img){
clearInterval(turn);
function2DisplayImg(imageN); // or do whatever
}
function imgTurn(){
if (imageN++ >= images.length) imageN = 0;
function2DisplayImg(imageN++);
}
</script>
You could replace the setInterval with setTimeout.
var turn = setTimeout(function(){imgTurn()},5000);
But then you need to use clearTimeout to stop it:
clearTimeout(turn);
But if you use setTimeout, you would need to setTimeout for the next image display, so you would not even need to clearTimeout to stop the rotation.
<img src="./images/image1.jpg" id="imageGallery" name="imageGallery"
onclick="chooseImg(this)" />
<script>
setTimeout(function(){imgTurn()},5000);
var images = function2CreateImgArray();
var imageN = 0;
var turn = 1;
function chooseImg(img){
turn = 0;
function2DisplayImg(imageN); // or do whatever
}
function imgTurn(){
if (turn==0) return;
if (imageN++ >= images.length) imageN = 0;
function2DisplayImg(imageN++);
}
</script>
I have been looking around and I cannot seem to figure out how to do this, although it seems like it would be very simple.(mobile development)
What I am trying to do is display a message (kind of like an alert, but not an alert, more like a dialog) while a calculation is being made. Simply like a Loading please wait. I want the message to appear and stay there while the calculation is being done and then be removed. I just cannot seem to find a proper way of doing this.
The submit button is pressed and first checks to make sure all the forms are filled out then it should show the message, it does the calculation, then hides the message.
Here is the Calculation function.
function scpdResults(form) {
//call all of the "choice" functions here
//otherwise, when the page is refreshed, the pulldown might not match the variable
//this shouldn't be a problem, but this is the defensive way to code it
choiceVoltage(form);
choiceMotorRatingVal(form);
getMotorRatingType();
getProduct();
getConnection();
getDisconnect();
getDisclaimer();
getMotorType();
//restore these fields to their default values every time submit is clicked
//this puts the results table into a known state
//it is also used in error checking in the populateResults function
document.getElementById('results').innerHTML = "Results:";
document.getElementById('fuse_cb_sel').innerHTML = "Fuse/CB 1:";
document.getElementById('fuse_cb_sel_2').innerHTML = "Fuse/CB 2:";
document.getElementById('fuse_cb_result').innerHTML = "(result1)";
document.getElementById('fuse_cb_res_2').innerHTML = "(result2)";
document.getElementById('sccr_2').innerHTML = "<b>Fault Rating:</b>";
document.getElementById('sccr_result').innerHTML = "(result)";
document.getElementById('sccr_result_2').innerHTML = "(result)";
document.getElementById('contactor_result').innerHTML = "(result)";
document.getElementById('controller_result').innerHTML = "(result)";
//Make sure something has been selected for each variable
if (product === "Choose an Option." || product === "") {
alert("You must select a value for every field. Select a Value for Product");
**************BLAH************
} else {
//valid entries, so jump to results table
document.location.href = '#results_a';
******This is where the message should start being displayed***********
document.getElementById('motor_result').innerHTML = motorRatingVal + " " + motorRatingType;
document.getElementById('voltage_res_2').innerHTML = voltage + " V";
document.getElementById('product_res_2').innerHTML = product;
document.getElementById('connection_res_2').innerHTML = connection;
document.getElementById('disconnect_res_2').innerHTML = disconnect;
if (BLAH) {
}
else {
}
populateResults();
document.getElementById('CalculatedResults').style.display = "block";
} //end massive else statement that ensures all fields have values
*****Close out of the Loading message********
} //scpd results
Thank you all for your time, it is greatly appreciated
It is a good idea to separate your display code from the calculation code. It should roughly look like this
displayDialog();
makeCalculation();
closeDialog();
If you are having trouble with any of those steps, please add it to your question.
Computers are fast. Really fast. Most modern computers can do several billion instructions per second. Therefore, I'm fairly certain you can rely on a a setTimeout function to fire around 1000ms to be sufficient to show a loading message.
if (product === "Choose an Option." || product === "") {
/* ... */
} else {
/* ... */
var loader = document.getElementById('loader');
loader.style.display = 'block';
window.setTimeout(function() {
loader.style.display = 'none';
document.getElementById('CalculatedResults').style.display = "block";
}, 1000);
}
<div id="loader" style="display: none;">Please wait while we calculate.</div>
You need to give the UI main thread a chance to render your message before starting your calculation.
This is often done like this:
showMessage();
setTimeout(function() {
doCalculation();
cleanUp()
}, 0);
Using the timer allows the code to fall through into the event loop, update the UI, and then start up the calculation.
You're already using a section to pop up a "results" page -- why not pop up a "calculating" page?
Really, there are 4,000,000 different ways of tackling this problem, but why not try writing a "displayCalculatingMessage" function and a "removeCalculatingMessage" function, if you don't want to get all object-oriented on such a simple thing.
function displayCalculatingMessage () {
var submit_button = getSubmitButton();
submit_button.disabled = true;
// optionally get all inputs and disable those, as well
// now, you can either do something like pop up another hidden div,
// that has the loading message in it...
// or you could do something like:
var loading_span = document.createElement("span");
loading_span.id = "loading-message";
loading_span.innerText = "working...";
submit_button.parentElement.replaceChild(loading_span, submit_button);
}
function removeCalculatingMessage () {
var submit_button = getSubmitButton(),
loading_span = document.getElementById("loading-message");
submit_button.disabled = false;
loading_span.parentElement.replaceChild(submit_button, loading_span);
// and then reenable any other disabled elements, et cetera.
// then bring up your results div...
// ...or bring up your results div and do this after
}
There are a billion ways of accomplishing this, it all comes down to how you want it to appear to the user -- WHAT you want to have happen.
I`m having a troubble with a simple thing.
I have an div, when clicked, an amination start (an infinite loop of images changing, simulating an animated gif).
But, when i click on the other div, the first one need to stop, and start just the other animation, and this goes on to every animation (will be 8 on total).
Here is the code for just one image loop:
var t1;
var t2;
var anim1 = new Array ('img/testes2/anim1_1.png','img/testes2/anim1_2.png');
var anim2 = new Array ('img/testes2/anim2_1.png','img/testes2/anim2_2.png');
var index = 1;
var verifica1 = 0;
var verifica2 = 0;
function rotateImage1(){
$('#imagemPrinc').fadeOut(0, function(){
$(this).attr('src', anim1[index]);
$(this).fadeIn(0, function(){
if (index == anim1.length-1){
index = 0;
}
else{
index++;
}
});
});
return false;
}
function stopTimer1(){
if(verifica1 = 1){
clearInterval(t2);
}
}
function muda1(){
if (verifica1 = 1){
//stopTimer2();
//$('#bgImagem').css({'background-image':'url(img/testes2/anim1_1.png)'});
t1 = setInterval(rotateImage1,500);
}
}
The same function for the second animation.
The verifica var, and the stopTimer function, i tried to make one stop, and just the other plays, but doesn't seems to be working. That's why it's commented on the code.
It will be easier to look the code running, so thats it ---HERE---
The clickable divs are those two Red Squares.
Someone can help me please!?
Thanks!
clearTimeout takes as argument the timer id returned by the setInterval function (here it's t1).
Instead of using fadeOut and fadeIn with a duration of 0, you should simply use hide and show.
As an aside, you can simplify this block :
if (index == anim1.length-1){
index = 0;
}
else{
index++;
}
in
index = [(index+1)%anim1.length];
And this is very wrong :
if(verifica1 = 1){
This is not a test : it always change verifica1 and is always true. You probably want ==.
Is there a point in your code where you (voluntarily) set verifica1 ?