Get user input for one minute, aggregating score - javascript

I'm new to javascript and html, which you can probably tell by my code. I am building a simple login game that will help kids practice logging onto devices at school. I want it to run for 1 minute while the game keeps score.
What I really need is a while loop that tests to see if a minute has passed, and during the minute, aggregates the score, resetting the user input fields each time. Coming from a C++ background, I'm really confusing myself going back and fourth between html and java. Specifically, I need that timer in java, and I need a while loop in game_login_entered that runs for a minute (or, I need said while loop in another java function, where it calls game_login_entered() repeatedly for 1 minute.
Thank you for taking the time to read this messy post. I hope I've been specific enough. Can anyone help me sort this out?
function credentials() {
var real_username = document.getElementById('real_username_field').value;
var un = document.getElementById('real_username');
var real_password = document.getElementById('real_password_field').value;
var pw = document.getElementById('real_password');
var teacher_confirmation = confirm("Check with your teacher. Is this correct?\nUsername: " + real_username + "\nPassword: " + real_password);
if (teacher_confirmation == true) {
//START GAME
//clear old stuff
$('.removeMe').hide();
//start timer (statically set at 60 seconds)
onTimer();
//show the hidden game time form.
$('.gametime').show();
} else {
return;
}
}
function game_login_entered() {
var real_password = document.getElementById('real_password_field').value;
var real_username = document.getElementById('real_username_field').value;
var pw = document.getElementById('game_password_field').value;
var un = document.getElementById('game_username_field').value;
var score = 0;
var multiplier = 1;
document.getElementById("game_password_field").style.borderColor = "gray";
document.getElementById("game_username_field").style.borderColor = "gray";
var x = 0;
if (pw == real_password && un == real_username) {
document.getElementById("user_feedback1").innerHTML = "CORRECT!";
document.getElementById("user_feedback2").innerHTML = "";
score = score + (100 * multiplier);
multiplier = multiplier + 1;
} else if (pw != real_password && un != real_username) {
document.getElementById("game_username_field").style.borderColor = "red";
document.getElementById("user_feedback1").innerHTML = "\nIncorrect username.\nEnter: " + real_username;
document.getElementById("game_password_field").style.borderColor = "red";
document.getElementById("user_feedback2").innerHTML = "\nIncorrect password.\nEnter: " + real_password;
multiplier = 1;
} else if (pw != real_password) {
document.getElementById("user_feedback1").innerHTML = "\nIncorrect password.\nEnter: " + real_password;
document.getElementById("game_username_field").style.borderColor = "gray";
document.getElementById("game_password_field").style.borderColor = "red";
document.getElementById("user_feedback2").innerHTML = "";
multiplier = 1;
} else if (un != real_username) {
document.getElementById("user_feedback1").innerHTML = "\nIncorrect username.\nEnter: " + real_username;
document.getElementById("game_username_field").style.borderColor = "red";
document.getElementById("game_password_field").style.borderColor = "gray";
document.getElementById("user_feedback2").innerHTML = "";
multiplier = 1;
}
document.getElementById("user_feedback_score").innerHTML = "Score: " + score;
document.getElementById("user_feedback_multiplier").innerHTML = "Multiplier: " + multiplier;
}
Body {
font-family: Calibri;
background-color: #3399FF;
color: #FFFFFF;
font-size: 18pt;
}
body {
font-size: 1.2em;
}
body input,
body button {
font-size: 1.2em;
}
form > div {
margin: 1em;
}
form button {
margin-left: auto;
margin-right: auto;
width: 50%;
}
label {
display: block;
}
input {
width: 50%;
padding: 0.2em;
}
button {
margin-left: auto;
margin-right: auto;
padding: 0.2em;
}
/*
Blinker
I'm not sure how this works, but hopefully it will allow me to blink the timer */
<style type="text/css"> .blink_text {
-webkit-animation-name: blinker;
-webkit-animation-duration: 1s;
-webkit-animation-timing-function: linear;
-webkit-animation-iteration-count: infinite;
-moz-animation-name: blinker;
-moz-animation-duration: 1s;
-moz-animation-timing-function: linear;
-moz-animation-iteration-count: infinite;
animation-name: blinker;
animation-duration: 1s;
animation-timing-function: linear;
animation-iteration-count: infinite;
color: red;
}
#-moz-keyframes blinker {
0% {
opacity: 1.0;
}
50% {
opacity: 0.0;
}
100% {
opacity: 1.0;
}
}
#-webkit-keyframes blinker {
0% {
opacity: 1.0;
}
50% {
opacity: 0.0;
}
100% {
opacity: 1.0;
}
}
#keyframes blinker {
0% {
opacity: 1.0;
}
50% {
opacity: 0.0;
}
100% {
opacity: 1.0;
}
}
</style>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
<h1 id="title" style="blink_text" align="center">Loginator!</h1>
<fieldset class=r emoveMe>
<legend>First, enter your BCPS One username and password:</legend>
<label>Username:
<input type="text" class=r emoveMe id="real_username_field" />
</label>
<br />
<label>Password:
<input type="text" class=r emoveMe id="real_password_field" />
</label>
<br />
<input type="submit" class=r emoveMe id="mySubmit" value="Submit" onclick="credentials()" class=r emoveMe/>
</fieldset>
<br />
<p1 class=r emoveMe><var id="real_username" class=r emoveMe></p1>
<br />
<p1 class = removeMe><var id="real_password" class = removeMe></p1>
<br />
<label class = gametime>Username:<input id="game_username_field" class = gametime></label>
<br />
<label class = gametime>Password: <input id="game_password_field" class = gametime></label>
<br />
<!-- While loop/timer should start here-->
<button id = "button_game_start" onclick="game_login_entered()" class = gametime>log in</button>
<br />
<p3 id = user_feedback1 class = gametime></p3>
<br />
<p3 id = user_feedback2 class = gametime></p3>
<br />
<p3 id = user_feedback_score class = gametime></p3>
<br />
<p3 id = user_feedback_multiplier class = gametime></p3>
<!--This jquery code should make the enter key work when the focus is in the password feild, but it doesn't...-->
<script>
$(#game_password_field).keyup(function(event){
if(event.keyCode == 13){
$(#button_game_start).click();
}
});
</script>
<!--This hides the game form. We will show it in credentials() when the game starts. -->
<script>
$('.gametime').hide();
</script>
<p id="demo"></p>
<!--This button starts the timer. The function is called in credentials(). I would like to put this in the java section so we could customize the timer.-->
<!-- <button onclick="onTimer()">Play!</button> -->
<div id="mycounter" class = gametime></div>
<script>
i = 60;
function onTimer() {
document.getElementById('mycounter').innerHTML = "Time left: " + i;
i--;
if (i < 0) {
alert("Time's up!");
$('.gametime').hide();
return;
}
else {
setTimeout(onTimer, 1000);
}
}
</script>

Since you want to aggregate every minute, use the setInterval function.
var score = 0;
var inputs = document.querySelectorAll("input");
setInterval(function() {
score++;
for (var i = 0; i < inputs.length; i++) {
inputs[i].value = "";
}
},60000);
Here's the updated fiddle
http://jsfiddle.net/b65902mm/1/

Related

Adding time between functions without affecting the typewriter effect

I'm trying to delay a function by using setInterval however it seems to be affecting a typewriting effect I have added to my text. The first <h1> works fine ie the typewriting effect starts from the first character of the sentence whereas the typewriting effect for the next <h2> starts from the 4th word and ignores the previous 3 words - I do believe this has to do with the milliseconds I have set on my setInterval.
var h1MessageArray = ["West Sussex Web Design"];
var h2MessageArray = ["Your down-to-earth website designer."];
var speed = 100;
var textPosition = 0;
typewriter1 = () => {
document.querySelector("#h1Message").innerHTML = h1MessageArray[0].substring(0,
textPosition) + '<span>\u25AE</span>';
if (textPosition++ != h1MessageArray[0].length) {
setTimeout("typewriter1()", speed);
}
}
window.addEventListener('load', typewriter1);
typewriter2 = () => {
document.querySelector("#h2Message").innerHTML = h2MessageArray[0].substring(0,
textPosition) + '<span>\u25AE</span>';
if (textPosition++ != h2MessageArray[0].length) {
setTimeout("typewriter2()", speed);
}
}
window.setInterval(typewriter2, 4000);
#typewriter {
width: fit-content;
margin: auto;
}
span {
animation: blinker 1s linear infinite;
}
#keyframes blinker {
50% {
opacity: 0;
}
}
#media(max-width:480px) {
#typewriter h2 {
font-size: 1rem;
}
}
<div class="container-fluid mt-5">
<div class="row">
<div class="col-12 text-center" id="typewriter">
<h1 id="h1Message"></h1>
<h2 id="h2Message"></h2>
</div>
</div>
</div>
What am I missing?
The problem is you are reusing textPosition in both functions. So the second function starts at the end of the position of the first function.
A simple solution is two different variables.
var h1MessageArray = ["West Sussex Web Design"];
var h2MessageArray = ["Your down-to-earth website designer."];
var speed = 100;
var textPosition1 = 0;
var textPosition2 = 0;
typewriter1 = () => {
document.querySelector("#h1Message").innerHTML = h1MessageArray[0].substring(0,
textPosition1) + '<span>\u25AE</span>';
if (textPosition1++ != h1MessageArray[0].length) {
setTimeout("typewriter1()", speed);
}
}
window.addEventListener('load', typewriter1);
typewriter2 = () => {
document.querySelector("#h2Message").innerHTML = h2MessageArray[0].substring(0,
textPosition2) + '<span>\u25AE</span>';
if (textPosition2++ != h2MessageArray[0].length) {
setTimeout("typewriter2()", speed);
}
}
window.setInterval(typewriter2, 4000);
#typewriter {
width: fit-content;
margin: auto;
}
span {
animation: blinker 1s linear infinite;
}
#keyframes blinker {
50% {
opacity: 0;
}
}
#media(max-width:480px) {
#typewriter h2 {
font-size: 1rem;
}
}
<div class="container-fluid mt-5">
<div class="row">
<div class="col-12 text-center" id="typewriter">
<h1 id="h1Message"></h1>
<h2 id="h2Message"></h2>
</div>
</div>
</div>

How to pause interval on mouseover and resume when the mouse is no longer over

I created a page where the background colors of a div change every so often. I want to make it so that when the mouse is over(or hovers) the color changer pauses where it is, as long as the mouse hovers there. And when the mouse no longer hovers the div, the colors continue to change where it left off. The closest examples I ran into on this website used JQuery solutions. I am not looking for a JQuery solution. I am looking for a javascript solution. I appreciate any and all of your responses. Thank You!
var dammit = document.getElementById("muck");
var colorChange = document.getElementById("color-changer");
var colors = ["red", "blue", "green", "pink"];
var counter = 0;
function changer() {
if (counter >= colors.length) {
counter = 0;
};
colorChange.style.background = colors[counter];
counter++;
};
var myTimer = setInterval(changer, 3000);
body {
background: #FDCA40;
margin: 0;
padding: 0;
-webkit-transition: background 0.9s;
-moz-transition: background 0.9s;
transition: background 0.9s;
}
div#muck {
width: 100%;
height: 100vh;
}
<body id="color-changer">
<div id="muck"></div>
</body>
There is no way to pause a timer, but you can just stop the currently running one and then start a new one.
(FYI: All browsers that are within 5 years old at least support CSS transitions. No need to vendor prefix that.)
var source = document.getElementById("muck");
var colorChange = document.getElementById("color-changer");
var colors = ["red", "blue", "green", "pink"];
var counter = 0;
function changer(){
if (counter >= colors.length){
counter = 0;
};
colorChange.style.background = colors[counter];
counter++;
};
var myTimer = setInterval(changer, 1000);
// Stop the current timer when mouseover
source.addEventListener("mouseover", function(){ clearInterval(myTimer)});
// Start a new timer when mouse out
source.addEventListener("mouseout", function(){ myTimer = setInterval(changer, 1000);});
body{
background: #FDCA40;
margin: 0;
padding: 0;
transition: background 0.9s;
}
div#muck{
width: 100%;
height: 100vh;
}
<body id="color-changer">
<div id="muck"></div>
</body>
You can do this purely in CSS but you need to use animation. I also added some CSS variables so the animation is easier to change.
body {
background: #FDCA40;
margin: 0;
padding: 0;
}
/* Safari 4.0 - 8.0 */
#-webkit-keyframes example {
from {background-color: red;}
to {background-color: yellow;}
}
#keyframes example {
0% {background-color: red;}
20% {background-color: blue;}
40% {background-color: green;}
80% {background-color: pink;}
100% {background-color: red;}
}
div#muck {
--animation-transition-speed: 0.9s;
--number-of-colors: 4;
width: 100%;
height: 100vh;
-webkit-animation-name: example;
-webkit-animation-duration: calc(var(--animation-transition-speed) * var(--number-of-colors));
animation-name: example;
animation-duration: calc(var(--animation-transition-speed) * var(--number-of-colors));
animation-iteration-count: infinite;
}
div#muck:hover {
animation-play-state: paused;
}
<body id="color-changer">
<div id="muck"></div>
</body>
While this doesnt really pouse the interval it mimics what you need very closely..
You can use a flag.. something like this:
var output = document.getElementById('id')
var isPaused = false;
var counter = 0;
window.setInterval(function() {
if(!isPaused) {
counter++;
if (counter >= colors.length) {
counter = 0;
};
colorChange.style.background = colors[counter];
}
}, 1000);
document.getElementById('muck').addEventListener('mouseenter', function(e) {
isPaused = true;
});
document.getElementById('muck').addEvenetListener('mouseleave', function(e) {
isPaused = false;
});
from Javascript - Pausing setInterval()

How to make the clock appear on the screen after the regressive disappears

I'm trying to make this clock that appears along with the beginning of the countdown only start after the element "GO!" to vanish. I already tried doing it starting after a setInterval of 6 seconds but I did not obtain result.
Please, if there is any way to debug this error even with css I thank you.
var tempo = new Number();
tempo = 180;
function start(){
var number = document.getElementById("number");
number.innerHTML = `<div id="cinco">5</div>
<div id="quatro">4</div>
<div id="tres">3</div>
<div id="dois">2</div>
<div id="um">1</div>
<div id="go">GO!</div>
`
ContagemRegressiva();
}
function ContagemRegressiva(){
if(tempo >= 0){
var minutos = parseInt(tempo / 60);
minutos = (minutos % 60);
var segundos = (tempo % 60);
if(minutos < 10){
minutos = '0' + minutos;
minutos = minutos.substr(0,2); //-->
}
if(segundos < 10){
segundos = '0' + segundos;
}
setTimeout('ContagemRegressiva()',1000);
tempo--;
regressivo.innerHTML = minutos + '<font color=black>:</font>' + segundos;
if((minutos == 00) && (segundos == 00)){
regressivo.innerHTML = minutos + '<font color=black>:</font>' + segundos + '<black></font>';
}
}
}
.container {
text-align: center;
margin: 0 auto;
}
#cinco,
#quatro,
#tres,
#dois,
#um,
#go {
font-size: 0;
animation: .5s ease-in-out 2 forwards alternate zoom;
}
#quatro {
animation-delay: 1s;
}
#tres {
animation-delay: 2s;
}
#dois {
animation-delay: 3s;
}
#um {
animation-delay: 4s;
}
#go {
animation-delay: 5s;
animation-iteration-count: 1;
}
#keyframes zoom {
0% {
font-size: 0;
}
100% {
font-size: 150px;
}
}
#keyframes some {
to {
transform: scale(0);
transform-origin: center top;
}
}
#number {
animation: 0.5s some linear forwards;
animation-delay: 6s;
}
.clock{
position: absolute;
top: 12%;
left: 92%;
transform: translate(-50%, -50%);
font-size: 25px;
color:black;
}
<body onload="start()">
<div id="number" class="container" />
<div class="clock">
<b style="font-size: 10"></b><span id="regressivo"></span></b><br>
</div>
</body>
You can use setTimeout function to call your ContagemRegressiva function.
function start() {
var number = document.getElementById("number");
number.innerHTML = `
<div id="cinco">5</div>
<div id="quatro">4</div>
<div id="tres">3</div>
<div id="dois">2</div>
<div id="um">1</div>
<div id="go">GO!</div>
`;
setTimeout(ContagemRegressiva, 6000);
}
You just need to find the amount of seconds to wait before running the function. I used 6000ms here.
Second way: you can add 'animationend' event to your #go element. When the animation on it ends, 'animationend' event will be fired.
So, you can do this with this code:
function start() {
var number = document.getElementById("number");
number.innerHTML = `
<div id="cinco">5</div>
<div id="quatro">4</div>
<div id="tres">3</div>
<div id="dois">2</div>
<div id="um">1</div>
<div id="go">GO!</div>
`;
var goElem = document.getElementById('go');
goElem.addEventListener('animationend', ContagemRegressiva);
}

Counter JS issue , doesn't toggle class every 1s

Counter doesn't work properly . I would like to get result when counterFun function toggle .active class and show number in every 1s. For now class is toggled but shows every 2nd number and it doesn't looks like it happen every 1sek
let clickNumber = 0;
const time = 1000;
const h1 = document.querySelector('h1');
function counterFun() {
clickNumber++;
h1.textContent = clickNumber;
h1.classList.toggle('active');
console.log(clickNumber);
}
setInterval(counterFun, time);
.regular {
opacity: 0;
}
.active {
font-size: 100px;
opacity: 1;
transition: .4s;
}
HTML
<div>
<h1 class="regular active">0</h1>
</div>
Your problem is you are using .toggle which doesn't toggle again until the second iteration. So basically you end up with:
0 - toggle
1 - off
2 - toggle
3 - off
Your options are to either use .remove and .add for the class or add a second .toggle.
Example with remove:
let clickNumber = 0;
const time = 1000;
const h1 = document.querySelector('h1');
function counterFun() {
h1.classList.remove('active');
clickNumber++;
h1.textContent = clickNumber;
h1.classList.add('active');
console.log(clickNumber);
}
setInterval(counterFun, time);
.regular {
opacity: 0;
}
.active {
font-size: 100px;
opacity: 1;
transition: .4s;
}
HTML
<div>
<h1 class="regular active">0</h1>
</div>
Example with Toggle:
let clickNumber = 0;
const time = 1000;
const h1 = document.querySelector('h1');
function counterFun() {
h1.classList.toggle('active');
clickNumber++;
h1.textContent = clickNumber;
h1.classList.toggle('active');
console.log(clickNumber);
}
setInterval(counterFun, time);
.regular {
opacity: 0;
}
.active {
font-size: 100px;
opacity: 1;
transition: .4s;
}
HTML
<div>
<h1 class="regular active">0</h1>
</div>
Because you need to remove and add the class at the same time, you can use this code
let clickNumber = 0;
const time = 1000;
const h1 = document.querySelector('h1');
function counterFun() {
$("#demo").addClass("active").delay(800).queue(function(next){
$(this).removeClass("active");
clickNumber++;
h1.textContent = clickNumber;
next();
});
console.log(clickNumber);
}
setInterval(counterFun, time);
.regular {
opacity: 0;
}
.active {
font-size: 100px;
opacity: 1;
transition-delay: .4s;
transition: .4s;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div>
<h1 class="regular active" id="demo">0</h1>
</div>
PS: you need jquery

Javascript CSS transition end firing at start of transition

I'm trying to build a simple slideshow where an image slides out for two seconds whilst another image appears beneath it.
(function ready(fn) {
if (document.readyState != 'loading') {
fn();
} else {
document.addEventListener('DOMContentLoaded', fn);
}
})(init);
function init() {
var pictureCollection = document.getElementsByClassName('slideshowimg');
var pictureTracker = document.getElementsByClassName('trackPoint');
var count = 0;
//load initial pic
pictureCollection[count].style.animation = 'fadein10 0.1s forwards';
pictureTracker[count].style.backgroundColor = 'black';
//Fade
var fadetime = setInterval(function() {
fading()
}, 5000);
function fading() {
pictureCollection[count].style.animation = 'fadeout10 2s forwards';
pictureTracker[count].style.backgroundColor = 'gray';
if (count == pictureCollection.length - 1) {
count = -1;
}
count++;
pictureCollection[count].style.animation = 'fadein10 2s forwards';
pictureTracker[count].style.backgroundColor = 'black';
}
function fixer(direction) {
//remove event listener to ensure it doesn't reset EVERY transition
event.target.removeEventListener('transitionend', fixer);
pictureCollection[count].style.animation = 'fadeout10 0.1s forwards';
pictureCollection[count].style.transform = 'translateX(0px)';
//reset counter
if (count === 3 && direction === "right") {
count = 0;
return;
}
if (count === 0 && direction === "left") {
count = 3;
return;
}
if (direction === "right") {
count++;
}
if (direction === "left") {
count--;
}
}
//add event listener to handle user clicks to each lside
for (i = 0; i < pictureCollection.length; i++) {
pictureCollection[i].addEventListener('click', function() {
//cancel autofade
clearInterval(fadetime);
//check where on pic user clicked
if (event.clientX > event.target.width / 2) {
event.target.style.animation = 'nofade10 0.1s forwards';
pictureTracker[count].style.backgroundColor = 'gray';
if (count === 3) {
pictureCollection[0].style.animation = 'fadein5 0.1s forwards';
pictureTracker[0].style.backgroundColor = 'black';
} else {
//bring next pic forwards and unhide
pictureCollection[count + 1].style.animation = 'fadein5 0.1s forwards';
pictureTracker[count + 1].style.backgroundColor = 'black';
}
//slide out right
event.target.style.transform = 'translateX(250px)';
//ensure that when the picture slides out it repositions behind
pictureCollection[count].addEventListener('transitionend', fixer('right'));
}
//or going left . . .
else {
pictureCollection[count].style.animation = 'nofade10 0.1s forwards';
pictureTracker[count].style.backgroundColor = 'gray';
if (count === 0) {
pictureCollection[3].style.animation = 'fadein5 0.1s forwards';
pictureTracker[3].style.backgroundColor = 'black';
} else {
//bring next pic forwards and unhide
pictureCollection[count - 1].style.animation = 'fadein5 0.1s forwards';
pictureTracker[count - 1].style.backgroundColor = 'black';
}
//slide out left
event.target.style.transform = 'translateX(-' + pictureCollection[count].width + 'px)';
//ensure that when the picture slides out it repositions behind
pictureCollection[count].addEventListener('transitionend', fixer("left"), false);
}
});
}
}
.slideshowimg {
height: 100%;
width: 100%;
position: inherit;
z-index: 0;
opacity: 0;
transition: all 2s ease-in-out;
}
#sliderCase {
overflow: hidden;
position: absolute;
z-index: 5;
background-color: black;
height: 150px;
width: 225px;
}
.trackPoint {
height: 10px;
width: 10px;
margin: 0 2px;
background-color: gray;
display: inline-block;
border-radius: 2em;
text-align: center;
position: relative;
top: 160px;
left: 75px;
}
#keyframes fadein10 {
from {
opacity: 0;
}
to {
opacity: 1;
z-index: 10;
}
}
#keyframes fadeout10 {
from {
opacity: 1;
}
to {
opacity: 0;
z-index: 0;
}
}
#keyframes fadein5 {
from {
opacity: 0;
}
to {
opacity: 1;
z-index: 5;
}
}
#keyframes nofade10 {
from {
opacity: 1;
}
to {
opacity: 1;
z-index: 10;
}
}
<!DOCTYPE html>
<html>
<head>
<meta charset='utf8'>
<script src='mainedit.js'></script>
<link rel='stylesheet' href='stylesedit.css' type='text/css'></link>
<title>Slideshow test</title>
</head>
<body>
<h1> Slideshow test: </h1>
<div id='sliderCase'>
<div style='background-color:red' class='slideshowimg'>pic 1</div>
<div style='background-color:blue' class='slideshowimg'>pic 2</div>
<div style='background-color:green' class='slideshowimg'>pic 3</div>
<div style='background-color:orange' class='slideshowimg'>pic 4</div>
</div>
<span class='trackPoint'></span>
<span class='trackPoint'></span>
<span class='trackPoint'></span>
<span class='trackPoint'></span>
</body>
</html>
It seems as if the transition end event is firing as the transition starts. Additionally the movement of slides seems to be inverted in the snippet, yet works locally.
I have used coloured divs in place of images for the sake of this example.
This isn't correct:
pictureCollection[count].addEventListener('transitionend', fixer("left"), false);
Here, you are calling and adding the return value of fixer("left") to the event listener, which isn't a valid value anyway.

Categories