Onmouseover method dynamically allocating - javascript

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>

Related

JavaScript itareate over divs and create a new one if doesn't fits

Hello guys I hope you can help me with JavaScript, I'm trying to itarate over some divs, the issue is that when I iterate sometimes a div never change to the other divs, it suppose to be infinite, I will recive thousands of different divs with different height and it should create an other div container in the case it does not fits but I can not achieve it work's, I'm using Vanilla JavaScript because I'm lerning JavaScript Regards.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<style>
.big_container{
height: 600px;
width: 150px;
background-color: #f1f1f1;
float: left;
}
.items{
background-color: gray;
height: 50px;
}
.new_container{
margin-bottom: 10px;
height: 300px;
width: 150px;
background-color: red;
float: left;
margin-left: 5px;
}
</style>
</head>
<body>
<div class="big_container">
<div class="items">1</div>
<div class="items">2</div>
<div class="items">3</div>
<div class="items">4</div>
<div class="items">5</div>
<div class="items">6</div>
<div class="items">7</div>
<div class="items">8</div>
<div class="items">9</div>
<div class="items">10</div>
<div class="items">11</div>
<div class="items">12</div>
<div class="items">13</div>
</div>
<div class="new_container">
</div>
</body>
<script>
number = 0
sum = 0
new_container = document.getElementsByClassName('new_container')[number].offsetHeight
divs = document.getElementsByClassName('items')
for ( var i = 0; i < divs.length; i++ ){
sum += this.document.getElementsByClassName( 'items' )[0].offsetHeight
if ( sum <= new_container ){
console.log(sum, "yes")
document.getElementsByClassName("new_container")[number].appendChild( this.document.getElementsByClassName( 'items' )[0] )
} else {
sum = 0
console.log(sum, "NO entra")
nuevo_contenedor = document.createElement('div'); // Creo un contenedor
nuevo_contenedor.className = "new_container";
nuevo_contenedor.setAttribute("style", "background-color: red;");
document.body.appendChild(nuevo_contenedor)
number += + 1
}
}
</script>
</html>
I really apreciate a hand.
I know that I'm late, but there is my approach how this can be done.
// generate items with different height
function generateItems(count) {
const arr = [];
for (let i = 0; i < count; i++) {
const div = document.createElement("DIV");
const height = Math.floor((Math.random() * 100) + 10);
div.setAttribute("style", `height: ${height}px`);
div.setAttribute("class", "items");
const t = document.createTextNode(i + 1);
div.appendChild(t);
arr.push(div);
}
return arr;
}
function createNewContainer(height) {
const new_container = document.createElement("DIV")
new_container.setAttribute("class", "new_container");
new_container.setAttribute("style", `height: ${height}px`)
document.body.appendChild(new_container);
return new_container;
}
function breakFrom(sourceContainerId, newContainerHeight) {
const srcContainer = document.getElementById(sourceContainerId);
const items = srcContainer.childNodes;
let new_container = createNewContainer(newContainerHeight);
let sumHeight = 0;
for (let i = 0; i < items.length; i++) {
let item = items[i];
if (item.offsetHeight > newContainerHeight) {
// stop!!! this item too big to fill into new container
throw new Error("Item too big.");
}
if (sumHeight + item.offsetHeight < newContainerHeight) {
// add item to new container
sumHeight += item.offsetHeight;
new_container.appendChild(item.cloneNode(true));
} else {
// create new container
new_container = createNewContainer(newContainerHeight);
new_container.appendChild(item.cloneNode(true));
// don't forget to set sumHeight)
sumHeight = item.offsetHeight;
}
}
// if you want to remove items from big_container
// for (let i = items.length - 1; i >= 0; i--) {
// srcContainer.removeChild(items[i]);
// }
}
// create big container with divs
const big_container = document.getElementById("big_container");
const items = generateItems(13);
items.forEach((div, index) => {
big_container.appendChild(div);
});
breakFrom("big_container", 300);
#big_container {
width: 150px;
background-color: #f1f1f1;
float: left;
}
.items {
background-color: gray;
border: 1px solid #000000;
text-align: center;
}
.new_container {
margin-bottom: 10px;
height: 300px;
width: 150px;
background-color: red;
border: 1px solid red;
float: left;
margin-left: 5px;
}
<div id="big_container"></div>
This example gives you the ability to play with divs of random height. Hope, this will help you.

How to change class and text of one tag by clicking on another tag?

I don't know how to describe this without making it more complicated.
So look at the result of the code and click on the first link with "Show", then the second one and third one.
When the second link is clicked, first one closes but text remains "Hide" and i want it to change to "Show".
So, when clicking a link, detect if any other link has text "Hide" and change it to "Show".
And please no jQuery...
document.getElementsByClassName("show")[0].onclick = function() {
var x = document.getElementsByClassName("hide")[0];
var y = document.getElementsByClassName("show")[0];
if (x.classList.contains("visible")) {
x.classList.remove("visible");
y.textContent = "Show";
} else {
closeOther();
x.classList.add("visible");
y.textContent = "Hide";
}
};
document.getElementsByClassName("show")[1].onclick = function() {
var x = document.getElementsByClassName("hide")[1];
var y = document.getElementsByClassName("show")[1];
if (x.classList.contains("visible")) {
x.classList.remove("visible");
y.textContent = "Show";
} else {
closeOther();
x.classList.add("visible");
y.textContent = "Hide";
}
};
document.getElementsByClassName("show")[2].onclick = function() {
var x = document.getElementsByClassName("hide")[2];
var y = document.getElementsByClassName("show")[2];
if (x.classList.contains("visible")) {
x.classList.remove("visible");
y.textContent = "Show";
} else {
closeOther();
x.classList.add("visible");
y.textContent = "Hide";
}
};
function closeOther() {
var visible = document.querySelectorAll(".visible"),
i, l = visible.length;
for (i = 0; i < l; ++i) {
visible[i].classList.remove("visible");
}
}
.style {
background-color: yellow;
width: 200px;
height: 200px;
display: inline-block;
}
.hide {
background-color: red;
width: 50px;
height: 50px;
display: none;
position: relative;
top: 50px;
left: 50px;
}
.hide.visible {
display: block;
}
<div class="style">
Show
<div class="hide">
</div>
</div>
<div class="style">
Show
<div class="hide">
</div>
</div>
<div class="style">
Show
<div class="hide">
</div>
</div>
I tried to write a solution which didn't use any javascript at all and worked using CSS alone. I couldn't get it to work though - CSS can identify focus but it can't identify blur (ie. when focus has just been removed).
So here is a solution which uses javascript and the classList API, instead:
var divs = document.getElementsByTagName('div');
function toggleFocus() {
for (var i = 0; i < divs.length; i++) {
if (divs[i] === this) continue;
divs[i].classList.add('show');
divs[i].classList.remove('hide');
}
this.classList.toggle('show');
this.classList.toggle('hide');
}
for (let i = 0; i < divs.length; i++) {
divs[i].addEventListener('click', toggleFocus, false);
}
div {
display: inline-block;
position: relative;
width: 140px;
height: 140px;
background-color: rgb(255,255,0);
}
.show::before {
content: 'show';
}
.hide::before {
content: 'hide';
}
div::before {
color: rgb(0,0,255);
text-decoration: underline;
cursor: pointer;
}
.hide::after {
content: '';
position: absolute;
top: 40px;
left: 40px;
width: 50px;
height: 50px;
background-color: rgb(255,0,0);
}
<div class="show"></div>
<div class="show"></div>
<div class="show"></div>
Like this?
Just added following to closeOther():
visible = document.querySelectorAll(".show"),
i, l = visible.length;
for (i = 0; i < l; ++i) {
visible[i].textContent="Show";
}

this.style.background is returning wrong value

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);
}

Javascript global variables not changing?!

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>

JQuery. Facing problems with click events

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>

Categories

Resources