I am working on the Odin project's javascript/jquery project to make an etcha sketch(of sorts). Initially the webpage loads fine, but when I attempt to change the size of the "gridval" with a prompt, only the box sizes change but not how many boxes fill the given space.
Thanks for your help in advance.
HTML
<!DCOTYPE html>
<html>
<head>
<title>Java Project</title>
<link rel="icon" href="https://www.codementor.io/assets/page_img/learn-javascript.png">
<link rel="stylesheet" type="text/css" href="css/style.css">
<script src="js/script.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
</head>
<body>
<button class="clear_button">Clear screen</button>
<div id="container"></div>
<script>creategrid();</script>
<script>hovereffect();</script>
</body>
</html>
CSS
#container{
width:400px;
height:400px;
background-color: #fc6;
}
.box{
width:52px;
height:52px;
display:inline-block;
margin: 1px;
background-color: #f86;
}
.clear_button{
background-color: #fc6;
color: #ffe;
border:none;
border-radius: 2px;
padding: 10px;
margin: 10px;
}
.clear_button:hover{
background-color: #426;
}
JavaScript
gridval = 16;
function creategrid(){
$(document).ready(function(){
//make grid code
for(var x = 0; x < gridval; x++){
for(var y = 0; y < gridval; y++){
var box = $("<div class='box'></div>");
box.appendTo('#container');
}
}
var width_height = 400/gridval - 2;
var box_class = document.querySelectorAll(".box");
for(var i = 0; i < box_class.length; i++){
box_class[i].style.width = width_height;
box_class[i].style.height = width_height;
}
//clear button code
$(".clear_button").click(function(){
$(".box").css("background-color", "#f86");
var val = gridval;
gridval = prompt("Please enter a value between 2 and 100 for the grid size!", val);
if(gridval != null) {
var width_height = 400/gridval - 2;
var box_class = document.querySelectorAll(".box");
for(var i = 0; i < box_class.length; i++){
box_class[i].style.width = width_height;
box_class[i].style.height = width_height;
}
}
});
});
}
//hover effect code
function hovereffect(){
$(document).ready(function(){
$(".box").hover(function(){
$(this).css("background-color", "#0ba");
}, function(){
$(this).css("background-color", "#9dd");
});
});
}
Your code needs a total reform, see the comments:
//The ready event will only be triggred once; on your page load.
$(function() {
//Default value
var gridval = 16;
/**
* Create the grid
*/
function createGrid(gridval) {
//make grid code
for (var x = 0; x < gridval; x++) {
for (var y = 0; y < gridval; y++) {
var box = $("<div class='box'></div>");
box.appendTo('#container');
}
}
var width_height = (400 / gridval) - 2;
var box_class = document.querySelectorAll(".box");
for (var i = 0; i < box_class.length; i++) {
box_class[i].style.width = width_height+'px'; //You needed +'px' here
box_class[i].style.height = width_height+'px'; //You needed +'px' here
}
}
//Execute the function on load
createGrid(gridval);
//Event delegation on since your elements will be created dynamically
$(document).on({mouseenter: function() {
$(this).css("backgroundColor", "#0ba");//backgroundColor instead of background-color
}, mouseleave: function() {
$(this).css("backgroundColor", "#9dd");
}}, ".box");
//clear button code
$(".clear_button").click(function() {
//$(".box").css("backgroundColor", "#f86"); // you don't need this all the elements will be removed!
var val = gridval;
gridval = prompt("Please enter a value between 2 and 100 for the grid size!", val);
if (gridval != null) {
//Empty the container
$("#container").empty();
createGrid(gridval);
}
});
});
#container {
width: 400px;
height: 400px;
background-color: #fc6;
}
.box {
width: 52px;
height: 52px;
/* Remove inline block */
display: block;
/* Add float*/
float:left;
margin: 1px;
background-color: #f86;
}
.clear_button {
background-color: #fc6;
color: #ffe;
border: none;
border-radius: 2px;
padding: 10px;
margin: 10px;
}
.clear_button:hover {
background-color: #426;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button class="clear_button">
Clear screen</button>
<div id="container"></div>
Related
I am trying to create a set of elements from CMS. I have reproduced the problem here with a set of rectangles that are being generated in Javascript. How can I dynamically add a "onmouseover" method to each one of them, that changes the colour of the block hovered?
for (i = 0; i < 5; i++) {
var coloured_div = document.createElement("div");
coloured_div.className = "col_div_class";
coloured_div.id = "coloured_div" + i;
document.getElementById("body").appendChild(coloured_div);
coloured_div.addEventListener("mouseover", hoverCube);
}
function hoverCube(i) {
document.getElementById("coloured_div" + i).style.backgroundColor = "orange";
}
.col_div_class {
width: 250px;
height: 250px;
background-color: yellow;
border: solid white 5px;
}
<body id="body">
</body>
As you're passing hoverCube as a callback to your event listener, it automatically gets passed an object which has information about the event (e). From this information, you can get the element which triggered the event by doing (e.target), which you can then set the style of:
for (var i = 0; i < 5; i++) {
var coloured_div = document.createElement("div");
coloured_div.className = "col_div_class";
coloured_div.id = "coloured_div" + i;
document.getElementById("body").appendChild(coloured_div);
coloured_div.addEventListener("mouseover", hoverCube);
}
function hoverCube(e) {
e.target.style.backgroundColor = "orange";
}
.col_div_class {
width: 250px;
height: 250px;
background-color: yellow;
border: solid white 5px;
}
<body id="body">
</body>
Alternatively, to achieve what you're trying to do in your code, you need to pass i as a parameter to hoverCube, which will then be able to access the correct element:
for (var i = 0; i < 5; i++) {
var coloured_div = document.createElement("div");
coloured_div.className = "col_div_class";
coloured_div.id = "coloured_div" + i;
document.getElementById("body").appendChild(coloured_div);
coloured_div.addEventListener("mouseover", (function(i) { // ES5 closure (if using ES6 you can simply change var i to let i in the for loop)
return function() {
hoverCube(i);
};
})(i)
)}
function hoverCube(i) {
document.getElementById("coloured_div" + i).style.backgroundColor = "orange";
}
.col_div_class {
width: 250px;
height: 250px;
background-color: yellow;
border: solid white 5px;
}
<body id="body">
</body>
Append event listener to all elements. Select them with querySelectorAll. No ids needed.
for (i = 0; i < 5; i++) {
var coloured_div = document.createElement("div");
coloured_div.className = "col_div_class";
document.getElementById("body").appendChild(coloured_div);
}
document.querySelectorAll('.col_div_class').forEach(function(el) {
el.addEventListener('mouseover', function(e) {
e.currentTarget.style.backgroundColor = "orange";
});
});
.col_div_class {
width: 250px;
height: 250px;
background-color: yellow;
border: solid white 5px;
}
<body id="body"></body>
You have 2 options here. The first is to use just CSS to accomplish the task.
for (i = 0; i < 5; i++) {
var coloured_div = document.createElement("div");
coloured_div.className = "col_div_class";
coloured_div.id = "coloured_div" + i;
document.getElementById("body").appendChild(coloured_div);
}
.col_div_class {
width: 250px;
height: 250px;
background-color: yellow;
border: solid white 5px;
}
.col_div_class:hover {
background-color: orange;
}
<body id="body">
</body>
If you must use Javascript, please see below.
for (i = 0; i < 5; i++) {
var coloured_div = document.createElement("div");
coloured_div.className = "col_div_class";
coloured_div.id = "coloured_div" + i;
document.getElementById("body").appendChild(coloured_div);
coloured_div.addEventListener("mouseover", function(e){e.currentTarget.style.backgroundColor = "orange";});
coloured_div.addEventListener("mouseout", function(e){e.currentTarget.style.backgroundColor = "yellow";});
}
.col_div_class {
width: 250px;
height: 250px;
background-color: yellow;
border: solid white 5px;
}
<body id="body">
</body>
I am trying to create a grid which takes a user input and uses that as its number of rows and columns. In other words, if the user inputs X, I want the grid to have X rows and X columns, and be square, meaning the boxes are as high as they are wide.
I have gotten it to work with JavaScript and CSS grid, but only if I already know the number of rows/columns, in that case 10. Please see below.
How can I create a grid that does the same but with any number of rows and columns?
#container {
display: grid;
grid-template-columns: repeat(10, 1fr);
width: 500px;
height: 500px;
}
div {
width: 100%;
height: 100%;
outline: 1px solid;
float: left;
}
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" type="text/css" href="style.css">
<title>Etch-a-sketch</title>
</head>
<body>
<h1>Etch-a-sketch</h1>
<button id="start">Start</button>
<div id="container"></div>
</body>
<script>
let btn = document.getElementById("start")
btn.addEventListener("click", createGrid)
function createGrid() {
let numberOfRows = prompt("How many rows do you want?");
let i = 0;
let x = numberOfRows ** 2;
for (i; i < x; i++) {
var div = document.createElement("div");
document.getElementById("container").appendChild(div);
div.addEventListener("mouseenter", function() {
this.style.backgroundColor = "red";
});
}
}
</script>
</html>
You can use CSS variable for that. and change the variable value using javascript.
let btn = document.getElementById("start")
btn.addEventListener("click", createGrid)
function createGrid() {
var Container = document.getElementById("container");
Container.innerHTML = '';
let numberOfRows = prompt("How many rows do you want?");
let i = 0;
let x = numberOfRows * numberOfRows;
document.documentElement.style.setProperty("--columns-row", numberOfRows);
for (i = 0; i < x ; i++) {
var div = document.createElement("div");
document.getElementById("container").appendChild(div);
div.addEventListener("mouseenter", function () {
this.style.backgroundColor = "red";
});
}
}
:root {
--columns-row: 2;
}
#container {
display: grid;
grid-template-columns: repeat(var(--columns-row), 1fr);
grid-template-rows: repeat(var(--columns-row), 1fr);
width: 500px;
height: 500px;
}
div {
border: 1px solid #000;
}
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" type="text/css" href="style.css">
<title>Etch-a-sketch</title>
</head>
<body>
<h1>Etch-a-sketch</h1>
<button id="start">Start</button>
<div id="container">
</div>
</body>
</html>
Change your css as per your need. jsfiddle.net/926pd5oh/9
<h1>Etch-a-sketch</h1>
<button id="start">Start</button>
<div id="container"></div>
<style>
#container>div {
width: 100%;
height: 10px;
margin: 2px;
}
#container>div>div {
float: left;
height: 10px;
border-right: 1px solid #ccc;
border-bottom: 1px solid #ccc;
width: 25px;
}
</style>
<script>
let btn = document.getElementById("start")
btn.addEventListener("click", createGrid);
function createGrid() {
let numberOfRows = prompt("How many rows do you want?");
document.getElementById("container").innerHTML = "";
console.log(numberOfRows);
for (let i = 0; i < numberOfRows; i++) {
var divRow = document.createElement("div");
document.getElementById("container").appendChild(divRow);
for (let y = 0; y < numberOfRows; y++) {
let divCol = document.createElement("div");
divCol.addEventListener("mouseenter", function () {
this.style.backgroundColor = "red";
});
divRow.appendChild(divCol);
}
}
}
</script>
I've ended up using a different tool: container.style.gridTemplateColumns and container.style.gridTemplateRows to affect the number of rows and columns of the container. This allows me not to use the :root function above. See JavaScript Syntax at https://www.w3schools.com/cssref/pr_grid-template-columns.asp
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" type="text/css" href="style.css">
<title>Etch-a-sketch</title>
</head>
<body>
<h1>Etch-a-sketch</h1>
<button id="start">Start</button>
<div id="container"></div>
</body>
<script>
//randomColor function is taken from http://www.devcurry.com/2010/08/generate-random-colors-using-javascript.html //
function randomRgb(value) {
col = "rgb("
+ randomColor(255) * value + ","
+ randomColor(255) * value + ","
+ randomColor(255) * value + ")";
}
function randomColor(num) {
return Math.floor(Math.random() * num);
}
function resetColorOfBoxes() {
boxes = document.querySelectorAll('div');
boxes.forEach(box => box.style.backgroundColor = "white");
}
function promptEntry() {
let userInput = prompt("How many rows would you like?", "Enter a number");
if (isNaN(userInput)) {
alert("That's not a valid entry. Try again");
promptEntry();
}
else {
createGrid(userInput);
}
}
function createGrid(numberOfRows) {
resetColorOfBoxes()
let gridTemplateColumns = 'repeat('+numberOfRows+', 1fr)'
var container = document.getElementById("container");
container.style.gridTemplateColumns = gridTemplateColumns;
container.style.gridTemplateRows = gridTemplateColumns;
let brightness = [];
let i = 0;
let numberOfBoxes = numberOfRows**2;
/*Create boxes*/
for (i; i < numberOfBoxes ; i++) {
brightness[i+1] = 1;
console.log(brightness);
var div = document.createElement("div");
div.classList.add(i+1);
document.getElementById("container").appendChild(div);
div.addEventListener("mouseenter", function () {
var className = this.className;
brightness[className] = brightness[className] - 0.1;
console.log(brightness[className]);
randomRgb(brightness[className]);
this.style.backgroundColor = col;
});
}
}
let btn = document.getElementById("start")
btn.addEventListener("click", promptEntry)
</script>
</html>
I am trying to create an RGB color guessing game. The premise is that each time someone clicks on a div, the function should retrieve it's color value and match it with the random color value(pre-selected) out of a given number of color values.
Now, the game has two difficulty levels. Easy and hard. The code for the two levels is almost same, the number of color divs in easy are 3, while in the case of hard, the number of color divs is 6.
However, while in easy mode, the function is retrieving a color value which belongs to none of the three divs. In fact, it is returning the background color value.
Here is the code
var colors = randomColors(6);
var easyColor = [];
var squares = document.querySelectorAll(".square");
function color() {
var a = Math.floor(Math.random()*250);
var b = Math.floor(Math.random()*250);
var c = Math.floor(Math.random()*250);
return "rgb("+ [(a),(b),(c)].join(', ') + ")";
}
function randomColors(num) {
var arr = [];
for(var i =0; i < num; i++) {
arr.push(color());
}
return arr;
}
// Tried to generate different set of colors for easy mode. Still working on it.
for(var x = 0; x < 3; x++) {
easyColor[x] = color();
}
var easyRandomColor = easyColor[Math.floor(Math.random()*easyColor.length)];
// selecting hard difficulty works same as playing again, hence the reload()
document.getElementById("hard").addEventListener("click", function() {
window.location.reload();
});
document.getElementById("reset").addEventListener("click", function() {
window.location.reload();
});
var squareColor;
// setting up the easy level of the game
document.getElementById("easy").addEventListener("click", function() {
document.getElementById("header").style.background = "#232323";
for(var y = 0; y < 3; y++) {
squares[y].style.background = easyColor[y];
}
for(var z = 3; z < 6; z++) {
squares[z].style.background = "#232323";
}
easyRandomColor = easyColor[Math.floor(Math.random()*easyColor.length)];
document.getElementById("guess").textContent = easyRandomColor;
// setting up the background colors of easy level squares
for(var j = 0; j < easyColor.length; j++)
squares[j].addEventListener("click", function() {
squareColor = this.style.background;
console.log(squareColor, easyRandomColor);
if(squareColor === easyRandomColor) {
document.getElementById("header").style.background = name;
document.getElementById("display").textContent = "Correct!";
document.getElementById("reset").textContent = "Play again?";
for(var k = 0; k < easyColor.length; k++) {
squares[k].style.background = name;
}
} else{
this.style.background = "#232323";
document.getElementById("display").textContent = "Try again.";
}
});
document.getElementById("easy").classList.add("selected");
document.getElementById("hard").classList.remove("selected");
});
var randomColor = colors[Math.floor(Math.random()*colors.length)];
//changing the RGB in h1 to rgb of one the squares
document.getElementById("guess").textContent = randomColor;
//assigning colors to the squares and adding the click event
for(var j = 0; j < squares.length; j++) {
squares[j].style.background = colors[j];
squares[j].addEventListener("click", function() {
var name = this.style.background;
// console.log(name, randomColor);
if(name === randomColor) {
document.getElementById("header").style.background = name;
document.getElementById("display").textContent = "Correct!";
document.getElementById("reset").textContent = "Play again?";
for(var k = 0; k < squares.length; k++) {
squares[k].style.background = name;
}
} else{
this.style.background = "#232323";
document.getElementById("display").textContent = "Try again.";
}
});
}
body {
background-color: #232323;
margin: 0;
}
html {
margin: 0;
padding: 0;
}
.square {
width: 30%;
/*background: purple;*/
padding-bottom: 30%;
float: left;
margin: 1.66%;
transition: 0.2s ease-in;
border-radius: 6%;
}
#container {
margin: 0 auto;
max-width: 600px;
}
h1, h3 {
color: white;
padding-top: 1%;
padding-bottom: 0.5%;
margin-top: 0;
margin-bottom: 0;
text-align: center;
}
#header {
transition: 0.2s ease-in;
}
#nav {
margin-top: 0;
padding-top: 0;
background: white;
max-width: 100%;
clear: left;
}
#nav p {
margin: 0 auto;
position: relative;
max-width: 580px;
}
#reset {
position: relative;
}
#hard {
position: absolute;
right: 0;
}
#easy {
position: absolute;
right: 50px;
}
#display {
position: relative;
left: 27%;
}
<!DOCTYPE html>
<html>
<head>
<title>RGBA Guess</title>
<link rel="stylesheet" type="text/css" href="colorgame.css">
</head>
<body>
<div id="header">
<h3>
The Great
</h3>
<h1>
<span id="guess">number</span>
</h1>
<h3>
Guessing Game
</h3>
</div>
<div id="nav">
<p>
<button id="reset">New Colors</button>
<span id="display"></span>
<button id="easy">Easy</button>
<button id="hard" class="selected">Hard</button>
</p>
</div>
<div id="container">
<div class="square" id="sqaure1"></div>
<div class="square" id="sqaure2"></div>
<div class="square" id="sqaure3"></div>
<div class="square" id="sqaure4"></div>
<div class="square" id="sqaure5"></div>
<div class="square" id="sqaure6"></div>
</div>
<script type="text/javascript" src="colorgame.js"></script>
</body>
</html>
I know, there is a better way to do this. I can instead call the randomColors(3) in easy mode, but I want to know what is it that I am doing wrong so that I can avoid it in the future.
Than You
The reason the function is retrieving the wrong colour in easy mode is because you did not remove your hard mode click event listeners from the elements.
To explain the weird behaviour you are seeing where the colour
being logged is rgb(35, 35, 35). What is happening is the original
click event still attached is running first, and going to the
statement's else condition and setting it to that colour. Ie. when you make a
block disappear. To understand this just run through in your head what
would happen if both those click events executed one after another.
First hard than easy.
What you instead want to do is attach your click events once, and use a declared function at global scope. Which you can use for both the easy clicks and hard clicks. The reason you want to declare it is so you can remove it from the hidden squares with removeEventListener.
So in the future, just remember to clean up your click events when changing states. That is the lesson to learn here.
JSFiddle fixing your bug:
https://jsfiddle.net/jx6y0gt1/5/
Here is a fixed code snippet:
var colors = randomColors(6);
var easyColor = [];
var squares = document.querySelectorAll(".square");
function color() {
var a = Math.floor(Math.random() * 250);
var b = Math.floor(Math.random() * 250);
var c = Math.floor(Math.random() * 250);
return "rgb(" + [(a), (b), (c)].join(', ') + ")";
}
function randomColors(num) {
var arr = [];
for (var i = 0; i < num; i++) {
arr.push(color());
}
return arr;
}
// Tried to generate different set of colors for easy mode. Still working on it.
for (var x = 0; x < 3; x++) {
easyColor[x] = color();
}
var easyRandomColor = easyColor[Math.floor(Math.random() * easyColor.length)];
// selecting hard difficulty works same as playing again, hence the reload()
document.getElementById("hard").addEventListener("click", function() {
window.location.reload();
});
document.getElementById("reset").addEventListener("click", function() {
window.location.reload();
});
var squareColor;
// setting up the easy level of the game
document.getElementById("easy").addEventListener("click", function() {
document.getElementById("header").style.background = "#232323";
for (var y = 0; y < 3; y++) {
squares[y].style.background = easyColor[y];
}
for (var z = 3; z < 6; z++) {
squares[z].style.background = "#232323";
squares[z].removeEventListener("click", squareClicked);
}
randomColor = easyColor[Math.floor(Math.random() * easyColor.length)];
document.getElementById("guess").textContent = easyRandomColor;
document.getElementById("easy").classList.add("selected");
document.getElementById("hard").classList.remove("selected");
});
var randomColor = colors[Math.floor(Math.random() * colors.length)];
//changing the RGB in h1 to rgb of one the squares
document.getElementById("guess").textContent = randomColor;
//assigning colors to the squares and adding the click event
for (var j = 0; j < squares.length; j++) {
squares[j].style.background = colors[j];
squares[j].addEventListener("click", squareClicked);
}
function squareClicked() {
var name = this.style.background;
// console.log(name, randomColor);
if (name === randomColor) {
document.getElementById("header").style.background = name;
document.getElementById("display").textContent = "Correct!";
document.getElementById("reset").textContent = "Play again?";
for (var k = 0; k < squares.length; k++) {
squares[k].style.background = name;
}
} else {
this.style.background = "#232323";
document.getElementById("display").textContent = "Try again.";
}
}
body {
background-color: #232323;
margin: 0;
}
html {
margin: 0;
padding: 0;
}
.square {
width: 30%;
/*background: purple;*/
padding-bottom: 30%;
float: left;
margin: 1.66%;
transition: 0.2s ease-in;
border-radius: 6%;
}
#container {
margin: 0 auto;
max-width: 600px;
}
h1,
h3 {
color: white;
padding-top: 1%;
padding-bottom: 0.5%;
margin-top: 0;
margin-bottom: 0;
text-align: center;
}
#header {
transition: 0.2s ease-in;
}
#nav {
margin-top: 0;
padding-top: 0;
background: white;
max-width: 100%;
clear: left;
}
#nav p {
margin: 0 auto;
position: relative;
max-width: 580px;
}
#reset {
position: relative;
}
#hard {
position: absolute;
right: 0;
}
#easy {
position: absolute;
right: 50px;
}
#display {
position: relative;
left: 27%;
}
<body>
<div id="header">
<h3>
The Great
</h3>
<h1>
<span id="guess">number</span>
</h1>
<h3>
Guessing Game
</h3>
</div>
<div id="nav">
<p>
<button id="reset">New Colors</button>
<span id="display"></span>
<button id="easy">Easy</button>
<button id="hard" class="selected">Hard</button>
</p>
</div>
<div id="container">
<div class="square" id="sqaure1"></div>
<div class="square" id="sqaure2"></div>
<div class="square" id="sqaure3"></div>
<div class="square" id="sqaure4"></div>
<div class="square" id="sqaure5"></div>
<div class="square" id="sqaure6"></div>
</div>
</body>
Changes I have made
Add this to the bottom of your code:
function squareClicked() {
var name = this.style.background;
// console.log(name, randomColor);
if(name === randomColor) {
document.getElementById("header").style.background = name;
document.getElementById("display").textContent = "Correct!";
document.getElementById("reset").textContent = "Play again?";
for(var k = 0; k < squares.length; k++) {
squares[k].style.background = name;
}
} else{
this.style.background = "#232323";
document.getElementById("display").textContent = "Try again.";
}
}
Use it as a listener with your elements like this:
for(var j = 0; j < squares.length; j++) {
squares[j].style.background = colors[j];
squares[j].addEventListener("click", squareClicked);
}
In your switch to easy mode, set the value of randomColor from your easy colors, and delete your loop to reattach the click events, they are already there.
randomColor = easyColor[Math.floor(Math.random()*easyColor.length)];
Also a secondary bug when you switch to easy mode you can still click the hidden squares. Deactivate those squares in easy mode so they can not be clicked:
for(var j = 3; j < squares.length; j++) {
squares[j].removeEventListener("click", squareClicked);
}
Im new to this but I've been having some trouble with trying to get my timer and score values back to 0 before a new game of memory starts. The values do reset, but don't show it until that value is affected. For example, the value for the number of matches never goes back to 0, it stays on 10(the max number of pairs) until you find the first match of the next game where it will then turn to 1. Does anybody know how to get the values to show 0 again when a new board is called up instead of just resetting when that value is affected?
I have already set
var turns = 0
var matches = 0
and called in them up as 0 in the function newBoard().
My timer code is:
var c = 0;
var t;
var timer_is_on = 0;
function timedCount() {
document.getElementById('txt').value = c;
c = c+1;
t = setTimeout(timedCount, 1000);
}
function startTimer() {
if (!timer_is_on) {
timer_is_on = 1;
timedCount();
}
}
function stopCount() {
clearTimeout(t);
timer_is_on = 0;
}
function resetTime(){
clearTimeout(t);
timer_is_on = 0;
c = 0
Where I have called up the resetTime() function in the function newBoard().
My full code is:
body{
background:#FFF;
font-family: Cooper Black;
}
h1{
font-family: Cooper Black;
text-align: center;
font-size: 64px;
color: #FF0066;
}
footer{
height: 150px;
background: -webkit-linear-gradient(#99CCFF, #FFF); /* For Safari 5.1 to 6.0 */
background: -o-linear-gradient(#99CCFF, #FFF); /* For Opera 11.1 to 12.0 */
background: -moz-linear-gradient(#99CCFF, #FFF); /* For Firefox 3.6 to 15 */
background: linear-gradient(#99CCFF, #FFF); /* Standard syntax (must be last) */
}
div#memory_board{
background: -webkit-radial-gradient(#FFF, #CC99FF); /* For Safari 5.1 to 6.0 */
background: -o-radial-gradient(#FFF, #CC99FF); /* For Opera 11.1 to 12.0 */
background: -moz-radial-gradient(#FFF, #CC99FF); /* For Firefox 3.6 to 15 */
background: radial-gradient(#FFF, #CC99FF); /* Standard syntax (must be last) */
border:#FF0066 10px ridge;
width:510px;
height:405px;
padding:24px;
}
div#memory_board > div{
background:url(tile_background.png) no-repeat;
border:#000 1px solid;
width:45px;
height:45px;
float:left;
margin:7px;
padding:20px;
cursor:pointer;
}
alert{
background: #FF0066;
}
button{
font-family: Cooper Black;
font-size: 20px;
color: #FF0066;
background: #5CE62E;
border: #C2E0FF 2px outset;
border-radius: 25px;
padding: 10px;
cursor: pointer;
}
input#txt{
background: yellow;
color: #FF0066;
font-family: Times New Roman;
font-size: 84px;
height: 150px;
width: 150px;
border-radius: 100%;
text-align: center;
border: none;
}
input#pause{
font-family: Cooper Black;
font-size: 18px;
color: #FF0066;
background: #C2E0FF;
border: #C2E0FF 2px outset;
border-radius: 25px;
padding: 10px;
cursor: pointer;
margin-top: 10px;
}
div.goes{
text-align: center;
border: #C2E0FF 5px double;
height: 160px;
width: 120px;
margin-top: 48px;
margin-left: 5px;
}
div.matches{
text-align: center;
border: #C2E0FF 5px double;
height: 160px;
width: 120px;
margin-top: 30px;
margin-left: 10px;
}
p{
font-size: 28px;
}
span{
font-family: Times New Roman;
font-size: 84px;
}
.sprite {
width:96px;
height:96px;
position: relative;
margin:15px;
}
.toon{
background: url(explode.png);
}
}
#dialogoverlay{
display: none;
opacity: 0.8;
position: fixed;
top: 0px;
left: 0px;
background: #FFF;
width: 100%;
z-index: 10;
}
#dialogbox{
display: none;
position: fixed;
background: #FF0066;
border-radius:7px;
width:400px;
z-index: 10;
}
#dialogbox > div{ background: #FFF; margin:8px; }
#dialogbox > div > #dialogboxhead{ background: linear-gradient(#99CCFF, #FFF); height: 40px; color: #CCC; }
#dialogbox > div > #dialogboxbody{ background: #FFF; color: #FF0066; font-size: 36px; text-align:center;}
#dialogbox > div > #dialogboxfoot{ background: linear-gradient(#FFF, #99CCFF); padding-bottom: 20px; text-align:center; }
<!DOCTYPE html>
<html>
<head>
<title>Memory Card Game</title>
<meta http-equiv="Content-type" content="text/html; charset=UTF-8" />
<link rel="stylesheet" type="text/css" href="reset.css" />
<link rel="stylesheet" type="text/css" href="text.css" />
<link rel="stylesheet" type="text/css" href="960.css" />
<link rel="stylesheet" type="text/css" href="mystyles.css" />
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
<script type='text/javascript' src='jquery.animateSprite.js'></script>
<script>
var memory_array = ['A','A','B','B','C','C','D','D','E','E','F','F','G','G','H','H','I','I','J','J'];
var memory_values = [];
var memory_tile_ids = [];
var tiles_flipped = 0;
var turns = 0
var matches = 0
Array.prototype.memory_tile_shuffle = function(){
var i = this.length, j, temp;
while(--i > 0){
j = Math.floor(Math.random() * (i+1));
temp = this[j];
this[j] = this[i];
this[i] = temp;
}
}
function newBoard(){
tiles_flipped = 0;
var output = '';
memory_array.memory_tile_shuffle();
for(var i = 0; i < memory_array.length; i++){
output += '<div id="tile_'+i+'" onclick="memoryFlipTile(this,\''+memory_array[i]+'\')"></div>';
}
document.getElementById('memory_board').innerHTML = output;
//fade in
$(document).ready(function () {
$('#memory_board > div').hide().fadeIn(1500).delay(6000)
});
resetTime();
turns = 0;
matches = 0;
}
function memoryFlipTile(tile,val){
startTimer();
playClick();
if(tile.innerHTML == "" && memory_values.length < 2){
tile.style.background = '#FFF';
tile.innerHTML = '<img src="' + val + '.png"/>';
if(memory_values.length == 0){
memory_values.push(val);
memory_tile_ids.push(tile.id);
} else if(memory_values.length == 1){
memory_values.push(val);
memory_tile_ids.push(tile.id);
if(memory_values[0] == memory_values[1]){
tiles_flipped += 2;
//sound
playMatch();
//animation
//number of clicks
turns = turns + 1;
document.getElementById("Count").innerHTML = turns;
//number of matches
matches = matches + 1;
document.getElementById("matchNumber").innerHTML = matches;
// Clear both arrays
memory_values = [];
memory_tile_ids = [];
// Check to see if the whole board is cleared
if(tiles_flipped == memory_array.length){
playEnd();
Alert.render("Congratulations! Board Cleared");
//resetTime()
//stopCount();
document.getElementById('memory_board').innerHTML = "";
newBoard();
}
} else {
function flipBack(){
// Flip the 2 tiles back over
var tile_1 = document.getElementById(memory_tile_ids[0]);
var tile_2 = document.getElementById(memory_tile_ids[1]);
tile_1.style.background = 'url(tile_background.png) no-repeat';
tile_1.innerHTML = "";
tile_2.style.background = 'url(tile_background.png) no-repeat';
tile_2.innerHTML = "";
//number of clicks
turns = turns + 1;
document.getElementById("Count").innerHTML = turns;
//clickNumber()
// Clear both arrays
memory_values = [];
memory_tile_ids = [];
}
setTimeout(flipBack, 700);
}
}
}
}
//timer
var c = 0;
var t;
var timer_is_on = 0;
function timedCount() {
document.getElementById('txt').value = c;
c = c+1;
t = setTimeout(timedCount, 1000);
}
function startTimer() {
if (!timer_is_on) {
timer_is_on = 1;
timedCount();
}
}
function stopCount() {
clearTimeout(t);
timer_is_on = 0;
}
function resetTime(){
clearTimeout(t);
timer_is_on = 0;
c = 0
}
//sound effects /*sounds from http://www.freesfx.co.uk*/
function playClick(){
var sound=document.getElementById("click");
sound.play();
}
function playMatch(){
var sound=document.getElementById("match_sound");
sound.play();
}
function playEnd(){
var sound=document.getElementById("finished");
sound.play();
}
//custom alert
function CustomAlert(){
this.render = function(dialog){
var winW = window.innerWidth;
var winH = window.innerHeight;
var dialogoverlay = document.getElementById('dialogoverlay');
var dialogbox = document.getElementById('dialogbox');
dialogoverlay.style.display = "block";
dialogoverlay.style.height = winH+"px";
dialogbox.style.left = (winW/2) - (400 * .5)+"px";
dialogbox.style.top = "200px";
dialogbox.style.display = "block";
document.getElementById('dialogboxhead').innerHTML = "";
document.getElementById('dialogboxbody').innerHTML = dialog;
document.getElementById('dialogboxfoot').innerHTML = '<button onclick="Alert.ok()">New Game</button>';
}
this.ok = function(){
document.getElementById('dialogbox').style.display = "none";
document.getElementById('dialogoverlay').style.display = "none";
}
}
var Alert = new CustomAlert();
</script>
<script>//sparkle effect: http://www.rigzsoft.co.uk/how-to-implement-animated-sprite-sheets-on-a-web-page/
$(document).ready(function(){
$("#memory_board").click(function animation(){
$(".toon").animateSprite({
columns: 10,
totalFrames: 50,
duration: 1000,
});
});
});
</script>
</head>
<body>
<audio id = "click" src = "click.mp3" preload = "auto"></audio>
<audio id = "match_sound" src = "match.mp3" preload = "auto"></audio>
<audio id = "finished" src = "finished.wav" preload = "auto"></audio>
<div id = "dialogoverlay"></div>
<div id = "dialogbox">
<div>
<div id = "dialogboxhead"></div>
<div id = "dialogboxbody"></div>
<div id = "dialogboxfoot"></div>
</div>
</div>
<div class = "container_16">
<div id = "banner" class = "grid_16">
<p><br></p>
<h1>Memory</h1>
</div>
<div class = "grid_3">
<input type="text" id="txt" value="0"/>
<p><br></p>
<p><br></p>
<div class = "goes">
<p>Turns <br><span id = "Count">0</span></p>
</div>
</div>
<div class = "grid_10">
<div id="memory_board"></div>
<script>newBoard();</script>
<div style="position: relative; height: 110px;">
<div class="sprite toon"></div>
</div>
</div>
<div class = "grid_3">
<button id = "new_game" onclick="newBoard()">New Game</button>
<input type="button" id="pause" value="Pause Game" onclick="stopCount()">
<p><br></p>
<p><br></p>
<p><br></p>
<div class = "matches">
<p>Matches <br><span id = "matchNumber">0</span></p>
</div>
</div>
</div>
<footer> </footer>
</body>
</html>
Both of the variables you are settings are displayed in HTML span objects.
What seems to be happening is that when you reset the Javascript variable, the value is being changed, but the span object where it is displayed to the user is being left at its previous value until it needs to be updated again.
As far as I can tell, your objects have the ids: matchNumber and Count for the match and turn variables respectively. If this is the case, try changing your code to reset the values to zero in the HTML when the variables are reset to zero.
For example:
// Reset the Javascript Count
var turns = 0
// Reset the HTML object
document.getElementById('Count').innerHTML = 0;
// Reset the Javascript Match Count
var matches = 0
// Reset the HTML object
document.getElementById('matchNumber').innerHTML = 0;
If I failed to explain this well, please comment and I'll try to clarify further.
I am not 100% sure, but you can try replacing your function with this one:
function timedCount() {
if(c>10){
//flipBack();
resetTime();
return;
}
document.getElementById('txt').value = c;
c = c+1;
t = setTimeout(timedCount, 1000);
}
I was writing code for image flip game in jquery but I am facing some problems with the click events on image in the beginning. The problems are when I click one image and click again the same image it works fine but if I click one image, the image src attribute is added to the img tag and then if I click any other image the src attribute is not added to that one for the first click because the clickCounter has the value 1 then. I employed my own logic (clickCounter). I am new to jquery. You may suggest a better way to do this. Thanks in advance.
Here is my code.
<style>
#main{
height: 500px;
border: 1px solid blue;
margin: auto;
}
.myimg{
width: 100px;
height: 100px;
background: lightblue;
background-position: center center;
margin: 10px;
float: left;
border-radius: 20px;
}
</style>
<body>
<div id="main">
</div>
<button id="add">Add</button>
<script src="jquery-1.11.2.js"></script>
<script>
var clickCounter = 0;
$('#add').click(function(){
addElements(44);
$('#add').attr('disabled', 'true');
});
function addElements(times){
var main = $('#main');
for(j = 1; j <= times; j++){
var i = document.createElement('img');
var img = $(i);
img.click(function(){
// $(this).css('background', 'url(back.png)');
var myImage = $(this);
if(clickCounter == 0){
myImage.attr('src', 'back.png');
myImage.attr('width', '100');
myImage.attr('height', '100');
clickCounter = 1;
}else{
myImage.removeAttr('src');
clickCounter = 0;
}
//alert(clickCounter);
});
img.addClass('myimg');
main.append(img);
}
}
</script>
</body>
JSFiddle
The problem is the shared variable clickCounter which is shared between all the elements.
In this case since you have dynamic elements, you could use event delegation and then use the current src value of the img to set the new one like
$('#add').click(function () {
addElements(44);
$('#add').prop('disabled', true);
});
$('#main').on('click', '.myimg', function () {
$(this).attr('src', function (i, src) {
return src == 'back.png' ? '' : 'back.png';
}).height(100).width(100);
})
function addElements(times) {
var $main = $('#main');
for (j = 1; j <= times; j++) {
$('<img />', {
'class': 'myimg'
}).appendTo($main)
}
}
Demo: Fiddle
Instead of counter, check for 'src' attribute as shown below,
$('#add').click(function(){
addElements(44);
$('#add').attr('disabled', 'true');
});
function addElements(times){
var main = $('#main');
for(j = 1; j <= times; j++){
var i = document.createElement('img');
var img = $(i);
img.click(function(){
// $(this).css('background', 'url(back.png)');
var myImage = $(this);
var attr = $(this).attr('src');
if(typeof attr == typeof undefined){
myImage.attr('src', 'back.png');
myImage.attr('width', '100');
myImage.attr('height', '100');
}else{
myImage.removeAttr('src');
}
//alert(clickCounter);
});
img.addClass('myimg');
main.append(img);
}
}
#main{
height: 500px;
border: 1px solid blue;
margin: auto;
}
.myimg{
width: 100px;
height: 100px;
background: lightblue;
background-position: center center;
margin: 10px;
float: left;
border-radius: 20px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id="main">
</div>
<button id="add">Add</button>