I made a website which consists of a display area that randomly spawns 50 circular <div> elements. I want to make it so when one of the circles is clicked, it comes to the foreground. I thought using the addEventListener function on each circle as it's created would work but I can't get it to do anything. Thank you.
HTML
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="utf-8">
<title></title>
<link rel="stylesheet" type="text/css" href="index_styling.css">
<script type="text/javascript" src="index_scripts.js"></script>
</head>
<header>
<h1>First Last, Assignment #6</h1>
</header>
<div id="orange_strip"></div>
<body>
<form>
<ul>
<li>
<input type="button" name="add" value="Add Square">
<input type="button" name="change" value="Change All Square Colors">
<input type="button" name="reset" value="Reset All Squares">
</li>
</ul>
<div id="display">
</div>
</form>
</body>
<footer>
<div id="copyright">Copyright © 2016 - First Mid Last</div>
</footer>
</html>
JavaScript
window.onload = function() {
for (var i = 0; i < 50; i++) {
var display_div = document.getElementById("display");
var circle = document.createElement("div");
var randNum = getRandomDimension(5000);
circle.setAttribute("class", "circle");
circle.style.backgroundColor = getRandomColor();
circle.style.position = "absolute";
circle.style.left = getRandomDimension(550);
circle.style.top = getRandomDimension(450);
circle.addEventListener("click", bringToFront(circle));
display.appendChild(circle);
}
}
function bringToFront(element) {
element.style.zIndex = "1";
}
function getRandomColor() {
var letters = "0123456789abcdef";
var result = "#";
for (var i = 0; i < 6; i++) {
result += letters.charAt(parseInt(Math.random() * letters.length));
}
return result;
}
function getRandomDimension(max) {
var num = Math.floor((Math.random() * max) + 1);
var str = num.toString();
return str += "px";
}
This line:
circle.addEventListener("click", bringToFront(circle));
...does not add an event listener. It calls your bringToFront() method immediately and then attempts to assign its return value as a listener except the return value is undefined. (Meanwhile, the effect of calling that function immediately within the loop means all of your divs get set to z-index: 1 upon their creation.)
You should be passing a reference to the function (note there is no () after the function name):
circle.addEventListener("click", bringToFront);
...and then change the function to work with this, because this will automatically be set to the clicked element at the time the function is called for the event:
function bringToFront() {
this.style.zIndex = "1";
}
The problem is with the current line
circle.addEventListener("click", bringToFront(circle));
That is trying to execute the bringToFront function right away.
AddEventListener just needs to function, and it will execute it when the event fires
circle.addEventListener("click", bringToFront);
Related
I am designing a quiz that generates the question & answers dynamically each time, I have written an if-else statement to check if the answer is right but something isn't quite right. The increment score function doesn't work properly as random numbers are added and the alert box pops up more than once. It seems there is a bounce within the function but I can't figure out what it is.
// Game controls
const startButton = document.getElementById('start-button');
const quitButton = document.getElementById('quit-button');
const mainHeading = document.getElementById('main-heading');
const gameContainer = document.getElementById('game-container');
const scoreOutput = document.getElementById('score-total');
var questionCountOutput = document.getElementById('question-count');
let currentScore = 0;
let questionCount = 0;
startButton.addEventListener('click', startGame);
quitButton.addEventListener('click', quitGame);
const maxQuestions = 10;
const scoreValue = 20;
// Start game
function startGame(event) {
startButton.classList.add('hidden')
mainHeading.classList.add('hidden')
gameContainer.classList.remove('hidden')
questionCount = 0;
currentScore = 0;
generateQuestion()
};
// Quit Game
function quitGame(event) {
if (window.confirm('Are you sure you want to quit?')) {
gameContainer.classList.add('hidden')
startButton.classList.remove('hidden')
}
};
// Generates the questions
function generateQuestion() {
// Increment question count by 1 each time
questionCount++;
questionCountOutput.innerText = `${questionCount}`;
// variables to help generate question
let countriesCount = countriesList.length;
let randomNumber = getRandomInt(0, countriesCount);
let chosenCountry = (countriesList[randomNumber].country); // Generate random country from array
let correctAnswer = (countriesList[randomNumber].capital); // Generate the correct capital city from array
// Define correct answer
let isCorrectQuestionAnswer = {
question: chosenCountry,
option: correctAnswer
};
// Generate 3 random cities from capitalListOptions to act as other answer options
let answerOption1 = (countriesList[getRandomInt(0, countriesList.length)].capital);
let answerOption2 = (countriesList[getRandomInt(0, countriesList.length)].capital);
let answerOption3 = (countriesList[getRandomInt(0, countriesList.length)].capital);
// define option outputs to loop through
let optionOutputs = [{
'question': chosenCountry,
'option': correctAnswer
},
{
'question': chosenCountry,
'option': answerOption1
},
{
'question': chosenCountry,
'option': answerOption2
},
{
'question': chosenCountry,
'option': answerOption3
}
];
// Randomise the outputs so the correct answer isn't in the same place all the time
randomOptionOutputs = optionOutputs.sort(() => Math.random() - 0.5);
let buttonOutputs = '';
let i = 0;
// Loop through the options and retrieve their key values
//add key values to as button attributes
Object.keys(randomOptionOutputs).forEach(function(key) {
// Code to define the html for the buttons
buttonOutputs += '<button id="answer-' + i + '" data-answer="' + randomOptionOutputs[key]['option'] + '" data-country="' + randomOptionOutputs[key]['question'] + '" class="answer-btn" >' + randomOptionOutputs[key]['option'] + '</button>';
i++;
});
// Create the answer buttons and the questionText
document.getElementById('country-name').innerHTML = chosenCountry;
document.getElementById('answers-container').innerHTML = buttonOutputs;
// Loop through the buttons that have been created and add event listeners to them
for (let i = 0; i < 4; i++) {
document.getElementById("answer-" + i).addEventListener("click", function() {
checkAnswer(isCorrectQuestionAnswer)
});
};
};
// Generate random number to use as array index to generate questions and answers
function getRandomInt(min, max) {
min = Math.ceil(min);
max = Math.floor(max);
return Math.floor(Math.random() * (max - min) + min); //The maximum is exclusive and the minimum is inclusive
};
// Checks if the answer selected is right, increments the score if it is, then moves on the to the next question
function checkAnswer(isCorrectQuestionAnswer) {
// Using a jquery method, retrieve the data-answer for the button clicked and compare this with the isCorrectQuestionAnswer object 'option'
$(document).on('click', '.answer-btn', function() {
var clickedButtonAnswer = $(this).data('answer');
// var clickedButtonQuestion = $(this).data('country');
if ((clickedButtonAnswer === isCorrectQuestionAnswer["option"])) {
$(this).addClass("correct");
incrementScore(scoreValue);
alert('Well done!!! You got that right');
generateQuestion();
return
} else {
$(this).addClass("incorrect");
alert("Ahhh that wasn't quite right - no worries, you'll get it next time!");
generateQuestion();
return
};
});
};
// function to increment the score with each new question
function incrementScore(num) {
currentScore += num;
scoreOutput.innerText = `${currentScore}`;
};
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="../assets/css/style.css">
<title>Around the World!</title>
</head>
<body>
<div class="navbar-container">
<nav class="navbar-top">
<ul>
<li>
Home
</li>
<li>
Rules
</li>
<li>
Play Game
</li>
<li>
High Scores
</li>
</ul>
</nav>
</div>
<div class="title-container">
<h1 id="main-heading">Let's Play</h1>
</div>
<div id="start-game" class="container">
<button id="start-button" class="btn">Start Game</button>
</div>
<div id="game-container" class="hidden">
<div id="progress-container">
<p class="progress">Question <span id="question-count"></span> of 10</p>
</div>
<div id="score-container">
<p class="progress">Score: <span id="score-total">0</span></p>
</div>
<div id="questions-container" class="container">
<h2 class="question">What is the capital city of <span id="country-name">country name</span>?</h2>
</div>
<div id="answers-container" class="container">
</div>
<div id="quit-game" class="container">
<button id="quit-button" class="btn">Quit Game</button>
</div>
</div>
<script src="../assets/js/script.js" defer></script>
<script src="../assets/js/quiz.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
</body>
</html>
I looked at a few examples on how to make a typewriter effect but my solution doesn't seem to work.I have three sentences that I want to loop forever and have them typed letter by letter to get that typewriter effect. Here is my code:
<html>
<head>
<meta charset="utf-8">
<title>Кухнята на Дани</title>
<link rel="stylesheet" href="css.css">
<script type="text/javascript" src="https://code.jquery.com/jquery-3.4.1.js"></script> <!--required for the next script-->
<!--some other javascript that requires the JQuery code above-->
<script type="text/javascript">
function typeWriter(){
var flag=0;
while(flag=0)
{
var s1 = "sentence1";
var s2 = "sentence2";
var s3 = "sentence3";
var s = "";
var i = 0;
document.getElementById("sub-element").innerHTML=s;
for(i=0; i<s1.length; i++)
{
s=s1.charAt(i);
document.getElementById("sub-element").innerHTML = document.getElementById("sub-element").innerHTML+s;
setTimeout(typeWriter, 50);
}
s="";
document.getElementById("sub-element").innerHTML=s;
for(i=0; i<s2.length;i++)
{
s=s2.charAt(i);
document.getElementById("sub-element").innerHTML = document.getElementById("sub-element").innerHTML+s;
setTimeout(typeWriter, 50);
}
s="";
document.getElementById("sub-element").innerHTML=s;
for(i=0; i<s3.length;i++)
{
s=s3.charAt(i);
document.getElementById("sub-element").innerHTML = document.getElementById("sub-element").innerHTML+s;
setTimeout(typeWriter, 50);
}
s="";
}
}
</script>
</head>
<body onload = "typeWriter()">
<header>
<!--header and navigation stuff here-->
</header>
<section id="home">
<div class="container">
<h1>Кухнята на Дани</h1>
<p id="sub-element"></p> <!--the text will appear in this paragraph-->
</div>
</section>
</body>
</html>
Due to some reason, the Javascript code won't work.
Excuse me for my code. I know it's too long but I decided to include everything that might be important.
You are using a while loop, meaning that even though you are appending one letter at a time it happens too fast (and in the same render frame) and thus you dont see the type effect.
You need to execute the function on some time interval, for example
setInterval(appendLetter, 200)
Which will execute appendLetter function every 200 ms and there you can have your chars append logic.
const text = "some text to loop"
let charIndex = 0;
function appendLetter() {
document.getElementById("aaa").innerHTML = text.substr(0, charIndex)
charIndex++;
if(charIndex > text.length) charIndex = 0;
}
setInterval(appendLetter, 250);
Try this
<section id="home">
<div class="container">
<h1>Кухнята на Дани</h1>
<p id="newmsg"></p> <!--the text will appear in this paragraph-->
</div>
</section>
Javascript code
var im = 0, ij=0;
var txtarray = ['sentence1', 'sentence2', 'sentence3'];
var speed = 100;
function typeWriter() {
if (im < txtarray[ij].length) {
document.getElementById("newmsg").innerHTML += txtarray[ij].charAt(im);
im++;
setTimeout(typeWriter, speed);
}
else{
setTimeout(repeatt, 1000);
}
}
typeWriter();
function repeatt() {
document.getElementById("newmsg").innerHTML = "";
im=0;
if(ij < txtarray.length-1){
ij++;
}
else{
ij = 0;
}
typeWriter();
}
I am trying to write a solution for a javascript application that takes a number input & depending on that number is how many times it runs a specific function. I am using a text box for input field & a button to process the number of times the user wants the function to run. It is for a game of dice game. User enters how many games he wants to play and clicks button to run the roll_dice function that many times. I'm not sure if I am going the right way with using a for loop to take users numeric input and loop through its value until it ends for example
function games() {
var num = document.getElementById("inp").vale;
var i;
for (i = 0; i < num; i++) {
roll_dice();
}
}
You have a typo. It's .value.
You can convert a string to a number by using * 1.
Something like this:
function games() {
var num = document.getElementById("inp").value * 1; // Convert the string value a number.
var i;
for (i = 0; i < num; i++) {
roll_dice();
}
}
function roll_dice() {
console.log("Test.");
}
var btnRun = document.getElementById("btnRun");
btnRun.onclick = function() {
games();
};
<input id="inp" type="text" />
<button id="btnRun" type="button">Run</button>
The value you get from input box is string you need to convert it into int . If you are using int in loop .
var num = parseInt(document.getElementById("inp").value);
function games() {
var num = document.getElementById("inp").value;
var i;
for (i = 0; i < Number(num); i++) {
roll_dice();
}
}
**<label>Game:</label><input type="text" id="input" value="0" />
<button id="btn">Submit</button>
<script>
document.getElementById("btn").addEventListener("click",function(){
var inputVal=document.getElementById("input").value*1;
rollDice(inputVal);
});
function rollDice(dice){
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>JS Bin</title>
</head>
<body>
<label>Game:</label><input type="text" id="input" value="0" />
<button id="btn">Submit</button>
<script>
document.getElementById("btn").addEventListener("click",function(){
var inputVal=document.getElementById("input").value*1;
rollDice(inputVal);
});
function rollDice(dice){
for(var i =0;i<dice;i++){
var x = Math.random()*100;
console.log(x);}
}
</script>
</body>
</html>
for(var i =0;i<dice;i++){
var x = Math.random()*100;
console.log(x);}
}
</script>**
I have a function called start that is triggered when you push the start button. The start function calls another function called getRandomImage. I want getRandomImage to repeat every 5 seconds, but I just can't get the setInterval method to work for me. I've tried putting the interval on the start function, but that just causes it to fire off once, and doesn't repeat. I've tried putting the interval on the getRandomImages function, but then it doesn't do anything. Essentially I am trying to make a color blindness test that flashes a random image every 5 seconds until 30 images have passed or the user clicks a button. I've been banging my head against this for over 8 hours, and am really questioning my choice in programming languages right now, lol.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8"
<title></title>
<link rel="stylesheet" href="ColorPerceptionTest.css">
</head>
<body>
<section>
<img src="Default.png" id="defaultimage">
<form>
<input type="button" id="Button1" value="" onClick="">
<input type="button" id="Button2" value="" onClick="">
<input type="button" id="Button3" value="" onClick="">
<br>
<input type="button" id="Start" value="Start" onClick="start()">
<input type="button" id="Help" value="Help" onClick="help()">
<br>
<p id="help"> </p>
</form>
</section>
<script>
var $ = function(id) {
return document.getElementById(id);
}
$("Button1").style.display = "none";
$("Button2").style.display = "none";
$("Button3").style.display = "none";
var imagesArray = ["3.gif", "05.gif", "5.gif", "6.gif", "7.gif",
"8.gif", "12.gif", "15.gif", "16.gif", "26.gif",
"29.gif", "42.gif", "45.gif", "73.gif",
"74.gif"];
var runTimer = setInterval(start, 5000);
function getRandomImage(imgAr, path) {
path = path || 'images/';
var num = Math.floor( Math.random() * imgAr.length );
var img = imgAr[ num ];
var imgStr = '<img src="' + path + img + '" alt = "">';
$("defaultimage").src = path + img;
$("Button1").style.display = "initial";
$("Button2").style.display = "initial";
$("Button3").style.display = "initial";
if(parseInt(img) < 8){
$("Button1").value = parseInt(img);
$("Button2").value = parseInt(img) - 2;
$("Button3").value = parseInt(img) + 1;
}else if(parseInt(img) > 7 && parseInt(img) < 29){
$("Button1").value = parseInt(img) - 2;
$("Button2").value = parseInt(img);
$("Button3").value = parseInt(img) + 1;
}else{
$("Button1").value = parseInt(img) - 5;
$("Button2").value = parseInt(img) - 9;
$("Button3").value = parseInt(img);
}
}
var start = function(){
$("help").innerHTML = "";
getRandomImage(imagesArray);
$("Start").style.display = "none";
$("Help").style.display = "none";
}
var help = function (){
$("help").innerHTML = "This is a test designed to help you determine" +
" if you have a problem with seeing colors. When you press start, a series of " +
"random images will be displayed. You have 5 seconds to read the number and " +
"select the correct button.";
}
</script>
</body>
Try moving the setInterval call to a point where start is defined...
Your code works fine in this fiddle.
var start = function(){
$("help").innerHTML = "";
getRandomImage(imagesArray);
$("Start").style.display = "none";
$("Help").style.display = "none";
}
var runTimer = setInterval(start, 5000);
Update: To make it more clear, had OP written function start() the posted code would have been properly hoisted. But, as he used a function expression, start is undefined when setInterval is called.
Another update: Here's a forked fiddle to correct the timer based on the button and the comments below.
I need help making a Countdown timer!
The user types a value into a text field, the timer starts when a button is clicked.
The timer text decreases by one every second until it reaches zero.
I have code for the first step, but can't seem to get the second step to work. I know it needs to include a setTimeout and loop.
Heres the code so far :
HTML-
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body>
<div id="form">
<h2> COUNTDOWN</h2>
Seconds: <input type="text" name="seconds" id="seconds" /> <input type="button" value="Start!" id="start" /> <input type="button" value="Pause" id="pause" />
</div>
<div id="info">
</div>
<div id="countdown">
</div>
<script src="script.js"></script>
</body>
</html>
JAVASCRIPT-
window.onload = function(){
var startButton = document.getElementById("start");
var form = document.getElementById("seconds");
var pause = document.getElementById("pause");
var secDiv = document.getElementById("countdown");
var editSec = document.createElement("h1");
startButton.onclick = function (){
editSec.innerHTML = form.value;
secDiv.appendChild(editSec);
};
};
Here it goes:
var globalTime = form.value; //receive the timer from the form
var secDiv = document.getElementById("countdown");
function decreaseValue() {
globalTime = globalTime - 1;
secDiv.innerHTML = globalTime;
}
startButton.onclick = function (){
setTimeout(decreasValue(),1000);
};
//clear out the timers once completed
You need to use setInterval, not setTimeout. Add this code to the onclick function:
editSec.id = "editSec";
window.cdint = setInterval(function(){
var origVal = parseInt(document.getElementById("editSec").innerHTML);
document.getElementById("editSec").innerHTML = origVal - 1;
if(origVal - 1 <= 0){
window.cdint = clearInterval(window.cdint);
}
}, 1000);
Use setInterval
var time = 100;
var countdown = function(){
secdiv.innerHTML = time;
time--;
}
setInterval(countdown,1000);
You can use setTimeout if you want :
startButton.onclick = function () {
var value = parseInt(form.value);
editSec.innerHTML = value;
secDiv.appendChild(editSec);
setTimeout(function () {
editSec.innerHTML = --value < 10
? '<span style="color:red">' + value + '</span>'
: value;
if (value) {
setTimeout(arguments.callee, 1000);
}
}, 1000);
};