Space between rows in a grid [duplicate] - javascript

This question already has answers here:
Align inline-block DIVs to top of container element
(5 answers)
Vertical space between two inline-block and a block element
(5 answers)
Image inside div has extra space below the image
(10 answers)
Closed 1 year ago.
I am trying to create a 16x16 grid.
Everything works perfectly except that I have some space between my rows, I can't figure out why.
The spacing between the columns is perfect but the rows have some gap between them.
Here's my code:
const container = document.getElementById("drawingGrid");
let rows = document.getElementsByClassName("gridRow");
let cells = document.getElementsByClassName("cell");
function createGrid() {
makeRows(16);
makeColumns(16);
}
// create rows
function makeRows(rowNum) {
for (r = 0; r < rowNum; r++) {
let row = document.createElement("div");
container.appendChild(row).className = "gridRow";
}
}
// create columns
function makeColumns(cellNum) {
for (i = 0; i < rows.length; i++) {
for (j = 0; j < cellNum; j++) {
let newCell = document.createElement("div");
rows[j].appendChild(newCell).className = "cell";
}
}
}
createGrid();
.cell {
border: 1px solid gray;
min-width: 10px;
min-height: 10px;
display: inline-block;
margin: 0;
padding: 0;
}
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>EtchASketch</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div id="drawingGrid">
</div>
<script src="app.js"></script>
</body>
</html>
And here's what it looks like on chrome:

You can turn the gridRow into a flexbox container. You can read the reason behind the space: Why does my image have space underneath? here.
const container = document.getElementById("drawingGrid");
let rows = document.getElementsByClassName("gridRow");
let cells = document.getElementsByClassName("cell");
function createGrid() {
makeRows(16);
makeColumns(16);
}
// create rows
function makeRows(rowNum) {
for (r = 0; r < rowNum; r++) {
let row = document.createElement("div");
container.appendChild(row).className = "gridRow";
}
}
// create columns
function makeColumns(cellNum) {
for (i = 0; i < rows.length; i++) {
for (j = 0; j < cellNum; j++) {
let newCell = document.createElement("div");
rows[j].appendChild(newCell).className = "cell";
}
}
}
createGrid();
.cell {
border: 1px solid gray;
min-width: 10px;
min-height: 10px;
display: inline-block;
margin: 0;
padding: 0;
}
.gridRow {
display: flex;
}
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>EtchASketch</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div id="drawingGrid">
</div>
<script src="app.js"></script>
</body>
</html>

You should define the height of your row:
.gridRow{
max-height:10px;
}
or setting the line-height of your row:
.gridRow{
line-height:10px;
}
or using flexbox as defined by m4n0.

Related

How can you force nested flexboxes to fill a desired space?

var tag = document.createElement("div");
var element = document.getElementById("container");
for(let i = 1; i<17; i++){
var tag = document.createElement("div");
tag.setAttribute('id', `row`)
tag.setAttribute('tag', `parent`)
element.appendChild(tag);
var elements = document.getElementById(`row`)
for(let j = 1; j<17; j++){
var tags = document.createElement("div");
tags.setAttribute('id', `${j}`)
tags.setAttribute('cell', `yes`)
tags.setAttribute('parent', `${i}`)
elements.appendChild(tags)
elements.removeAttribute("id")
//console.log(elements)
}
}
var cells = document.querySelectorAll('parent')
addEventListener('mouseover', function(e) {
const selectedCell = e.path[0]
//console.log(selectedCell.getAttribute('parent'))
//console.log(typeof selectedCell.getAttribute('parent'))
if(typeof selectedCell.getAttribute('parent') === 'string'){
selectedCell.setAttribute('selected', 'true')
//console.log(selectedCell)
}
})
#container {
display: flex;
flex-wrap: wrap;
align-items: baseline;
align-content: stretch;
height: 960px;
width: 960px;
}
div[tag]{
display: flex;
flex-direction: row;
height: 60px;
width: 100%;
flex-grow: 1;
}
[tag] > [id]{
display: flex;
height: 60px;
flex-direction: row;
flex-grow: 1;
}
div[selected]{
background-color: black;
}
<!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">
<title>Document</title>
<link rel="stylesheet" href="stylesheet.css">
</head>
<body>
<div id="container">
</div>
<script src = "app.js"></script>
</body>
</html>
I am currently on the tail end of the introductory front-end course from OdinProject, however, I am stuck on the etch-a-sketch assignment. The CSS (located below) will only fill out properly if I set a fixed height in pixels.
div#container {
border-color: red;
height: 960px;
width: 960px;
flex-direction: row;
}
div[tag*="parent"]{
display: flex;
flex-direction: row;
height: auto;
width: 100%;
flex-grow: 1;
}
div[cell*="yes"]{
display: flex;
height: auto;
flex-direction: row;
flex-grow: 1;
}
div[selected]{
background-color: black;
}
If I set the height to auto (as present in the current styling), the width is fine, which is 960 pixels, but the height of the rows and the cells will be 0 pixels. Setting the height as a fixed height is okay in this scenario which is a 16x16 etch-a-sketch, however, I am planning to allow the user to select the number of cells, which would require the height to be dynamic. I have tried everything and nothing seems to work. This is my first question here, so I don't know if you will require the other code, so I will just paste it below.
var tag = document.createElement("div");
var element = document.getElementById("container");
for(let i = 1; i<17; i++){
var tag = document.createElement("div");
tag.setAttribute('id', `row`)
tag.setAttribute('tag', `parent`)
element.appendChild(tag);
var elements = document.getElementById(`row`)
for(let j = 1; j<17; j++){
var tags = document.createElement("div");
tags.setAttribute('id', `${j}`)
tags.setAttribute('cell', `yes`)
tags.setAttribute('parent', `${i}`)
elements.appendChild(tags)
elements.removeAttribute("id")
console.log(elements)
}
}
var cells = document.querySelectorAll('parent')
addEventListener('mouseover', function(e) {
const selectedCell = e.path[0]
//console.log(selectedCell.getAttribute('parent'))
console.log(typeof selectedCell.getAttribute('parent'))
if(typeof selectedCell.getAttribute('parent') === 'string'){
selectedCell.setAttribute('selected', 'true')
console.log(selectedCell)
}
})
<!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">
<title>Document</title>
<link rel="stylesheet" href="stylesheet.css">
</head>
<body>
<div id="container">
</div>
<script src = "app.js"></script>
</body>
</html>
I changed the height and width on div#container to 100vh and 100vw. This is so that the container fills the whole viewport, which is what you want as I understand.
I removed the height:auto on the parent and cell classes and I also removed width:100%
I created a variable called gridSize with let. I replaced the 17 with this variable gridSize in the two loops and I added the following to calculate the height of the cell:
let cellHeight = Math.floor((100 / gridSize) * 1000) / 1000 + "vh";
And, then I set the height of the cell dynamically with:
tags.style.height = gridSize
which effectively is the same as:
tags.style.height = "10vh" // if gridSize is 10
tags.style.height = "5vh" // if gridSize is 20
You should be able to implement the functionality to allow the user to dynamically select the grid size. This demo should show you the way forward.
var tag = document.createElement("div");
var element = document.getElementById("container");
let gridSize = 17;
let cellHeight = Math.floor((100 / gridSize) * 1000) / 1000 + "vh";
for (let i = 1; i < gridSize; i++) {
var tag = document.createElement("div");
tag.setAttribute('id', `row`)
tag.setAttribute('tag', `parent`)
element.appendChild(tag);
var elements = document.getElementById(`row`)
for (let j = 1; j < gridSize; j++) {
var tags = document.createElement("div");
tags.setAttribute('id', `${j}`)
tags.setAttribute('cell', `yes`)
tags.setAttribute('parent', `${i}`)
tags.style.height = cellHeight;
elements.appendChild(tags)
elements.removeAttribute("id")
}
}
var cells = document.querySelectorAll('parent')
addEventListener('mouseover', function(e) {
const selectedCell = e.path[0]
if (typeof selectedCell.getAttribute('parent') === 'string') {
selectedCell.setAttribute('selected', 'true')
}
})
div#container {
border-color: red;
height: 100vh;
width: 100vw;
flex-direction: row;
}
div[tag*="parent"] {
display: flex;
flex-direction: row;
flex-grow: 1;
}
div[cell*="yes"] {
display: flex;
flex-direction: row;
flex-grow: 1;
}
div[selected] {
background-color: black;
}
<div id="container"></div>

On mouseover Event Listener not changing color of grid item/div

Kind of a JavaScript noob here. I'm using DOM manipulation for a project and need to make it so that the grid items in my container change color after being hovered on. Why won't my hoverColor() function do anything? I assume that it is a problem with my "grid-item" class not working right.
I haven't adjusted the container sizing options yet, just trying to make the event listener work first.
//query selectors
const container = document.querySelector('#container');
//Function that creates GRID
function addDivs(rows, cols){
container.style.setProperty('--grid-rows', rows);
container.style.setProperty('--grid-cols', cols);
for (i = 0; i < (rows * cols); i++){
let square = document.createElement("div");
square.classList.add('grid-item');
container.appendChild(square);
}
hoverColor();
}
//function that creates a random color
let randomColor = function() {
var letters = '0123456789ABCDEF';
var color = '#';
for (var i = 0; i < 6; i++) {
color += letters[Math.floor(Math.random() * 16)];
}
return color;
}
//function that changes div color uponed being hovered
function hoverColor() {
let item = document.querySelector('.grid-item');
item.addEventListener('mouseover', () => {
item.style.backgroundColor = `${randomColor()}`;
});
}
//grid creationg
addDivs(16, 16);
:root {
--grid-cols: 1;
--grid-rows: 1;
}
#container {
display: grid;
grid-gap: 0.5em;
grid-template-rows: repeat(var(--grid-rows), 1fr);
grid-template-columns: repeat(var(--grid-cols), 1fr);
border: 3px solid black;
padding: 1em;
}
#container:hover {
box-shadow: 0 5px 5px rgba(0,0,0,0.19), 0 5px 5px rgba(0,0,0,0.23);
}
.grid-item {
padding: 1em;
border: 1px solid #ddd;
text-align: center;
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>repl.it</title>
<link href="style.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div id="container"></div>
<script src="script.js"></script>
</body>
</html>
There were two problems with your code:
Most fundamentally, you forgot to call your randomColor function. You were trying to stringify the function value itself as a CSS color value, which was never going to work. randomColor() is instead what you wanted, the color returned by the function.
Your function would have only worked on the first grid item, because you were using querySelector, which only selects the first HTML element in the collection of matched elements. You instead want to use querySelectorAll, and iterate through the collection, adding the event listener to each.
See working example below, with both fixes made:
//query selectors
const container = document.querySelector('#container');
//Function that creates GRID
function addDivs(rows, cols){
container.style.setProperty('--grid-rows', rows);
container.style.setProperty('--grid-cols', cols);
for (i = 0; i < (rows * cols); i++){
let square = document.createElement("div");
square.classList.add('grid-item');
container.appendChild(square);
}
hoverColor();
}
//function that creates a random color
let randomColor = function() {
var letters = '0123456789ABCDEF';
var color = '#';
for (var i = 0; i < 6; i++) {
color += letters[Math.floor(Math.random() * 16)];
}
return color;
}
//function that changes div color uponed being hovered
function hoverColor() {
let items = document.querySelectorAll('.grid-item');
items.forEach(item => {
item.addEventListener('mouseover', () => {
item.style.backgroundColor = `${randomColor()}`;
});
});
}
//grid creationg
addDivs(16, 16);
:root {
--grid-cols: 1;
--grid-rows: 1;
}
#container {
display: grid;
grid-gap: 0.5em;
grid-template-rows: repeat(var(--grid-rows), 1fr);
grid-template-columns: repeat(var(--grid-cols), 1fr);
border: 3px solid black;
padding: 1em;
}
#container:hover {
box-shadow: 0 5px 5px rgba(0,0,0,0.19), 0 5px 5px rgba(0,0,0,0.23);
}
.grid-item {
padding: 1em;
border: 1px solid #ddd;
text-align: center;
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>repl.it</title>
<link href="style.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div id="container"></div>
<script src="script.js"></script>
</body>
</html>
Try this.
Mistakes you did:
You have to attach the eventListener to every element. For starters, querySelector only takes first element. Even if you did use querySelectorAll, you would get a NodeList (sort of an array of Elements), you would still need to loop through each and add the event listener to every one.
In my solution I just add it immediately after you create it in the loop you present in addDivs. Saves looping twice.
You can then reference to the hoverColor function as I did in my example.
In the hoverColor function you will, by default, receive an Event($event) object (in your case MouseEvent). Among multiple properties, the Event object will have a target property which references your Element. You can then modify the style.backgroundColor property to the color of your choice.
Hope it is what you have wanted.
//query selectors
const container = document.querySelector('#container');
//Function that creates GRID
function addDivs(rows, cols){
container.style.setProperty('--grid-rows', rows);
container.style.setProperty('--grid-cols', cols);
for (i = 0; i < (rows * cols); i++){
let square = document.createElement("div");
square.addEventListener('mouseover', hoverColor);
square.classList.add('grid-item');
container.appendChild(square);
}
}
//function that creates a random color
let randomColor = function() {
var letters = '0123456789ABCDEF';
var color = '#';
for (var i = 0; i < 6; i++) {
color += letters[Math.floor(Math.random() * 16)];
}
return color;
}
//function that changes div color uponed being hovered
function hoverColor($event) {
const item = $event.target;
item.style.backgroundColor = `${randomColor()}`;
}
//grid creationg
addDivs(16, 16);
I have found a solution to your problem
//query selectors
const container = document.querySelector('#container');
//Function that creates GRID
function addDivs(rows, cols){
container.style.setProperty('--grid-rows', rows);
container.style.setProperty('--grid-cols', cols);
for (i = 0; i < (rows * cols); i++){
let square = document.createElement("div");
square.classList.add('grid-item');
container.appendChild(square);
}
hoverColor();
}
//function that creates a random color
let randomColor = function() {
var letters = '0123456789ABCDEF';
var color = '#';
for (var i = 0; i < 6; i++) {
color += letters[Math.floor(Math.random() * 16)];
}
return color;
}
//function that changes div color uponed being hovered
function hoverColor() {
let items = document.querySelectorAll('.grid-item'); // Get all the elements with .grid-item (not just the first one
for (let i = 0; i < items.length; i++) { // Add for loop to add an event listener to all .grid-item elements
items[i].addEventListener('mouseover', () => {
items[i].style.backgroundColor = `${randomColor()}`; // randomColor function not being called
// randomColor -> randomColor()
});
}
}
//grid creationg
addDivs(16, 16);
:root {
--grid-cols: 1;
--grid-rows: 1;
}
#container {
display: grid;
grid-gap: 0.5em;
grid-template-rows: repeat(var(--grid-rows), 1fr);
grid-template-columns: repeat(var(--grid-cols), 1fr);
border: 3px solid black;
padding: 1em;
}
#container:hover {
box-shadow: 0 5px 5px rgba(0,0,0,0.19), 0 5px 5px rgba(0,0,0,0.23);
}
.grid-item {
padding: 1em;
border: 1px solid #ddd;
text-align: center;
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>repl.it</title>
<link href="style.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div id="container"></div>
<script src="script.js"></script>
</body>
</html>
What I changed
querySelector()
querySelector() to querySelectorAll().
querySelector() will only select the first element it finds in the document querySelectorAll() will select every element in the document with that selector.
randomColor
randomColor to randomColor()
randomColor will return the function randomColor() will run the function.
Added a for loop
The for loop adds an event listener to all the elements with the class name .grid-item.

Bind a block to cells in a table

when scrolling a table, the blue block in it does not move along with the cells, can this be somehow fixed?
ignore this text, I just don’t know what else to write -> It looks like your post is mostly code; please add some more details.It looks like your post is mostly code; please add some more details.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
.container {
overflow: auto;
width: 75%;
}
td {
border: 1px solid #000;
width: 40px;
height: 20px;
color: #fff;
}
.cell {
background-color: blue;
position: absolute;
z-index: 2;
}
</style>
</head>
<body>
<div class="container"></div>
<script>
function getPosition(el) {
let rect = el.getBoundingClientRect(),
scrollLeft = window.pageYOffset || document.documentElement.scrollLeft,
scrollTop = window.pageYOffset || document.documentElement.scrollTop
return {
top: rect.top + scrollTop,
left: rect.left + scrollLeft
}
}
function tableInit(parent, row, cols) {
const table = document.createElement('table')
let counter = 0
for (let i = 0; i < row; i++) {
let tr = document.createElement('tr')
for (let j = 0; j < cols; j++, counter++) {
let td = document.createElement('td')
td.textContent = counter
td.classList.add(counter)
tr.appendChild(td)
}
table.appendChild(tr)
}
parent.appendChild(table)
}
let container = document.querySelector('.container')
tableInit(container, 7, 100)
let table = document.querySelector('table')
let td = document.getElementsByClassName('104')[0]
let cell = document.createElement('div')
cell.classList.add('cell')
cell.setAttribute('style',
`top: ${getPosition(td).top}px;
left: ${getPosition(td).left}px;
height: ${td.clientHeight + 2}px;
width: ${td.clientWidth * 2}px;`)
table.appendChild(cell)
</script>
</body>
</html>
You need to give your table or your container a position, so that your browser knows how it flows in the DOM. Without this, your .cell is absolute to the container not the scrolling children.
Watch out for the second line in tableInit(). That's one possible solution.
function getPosition(el) {
let rect = el.getBoundingClientRect(),
scrollLeft = window.pageYOffset || document.documentElement.scrollLeft,
scrollTop = window.pageYOffset || document.documentElement.scrollTop
return {
top: rect.top + scrollTop,
left: rect.left + scrollLeft
}
}
function tableInit(parent, row, cols) {
const table = document.createElement('table')
table.setAttribute('style', `position: relative`) // Give the table a position
let counter = 0
for (let i = 0; i < row; i++) {
let tr = document.createElement('tr')
for (let j = 0; j < cols; j++, counter++) {
let td = document.createElement('td')
td.textContent = counter
td.classList.add(counter)
tr.appendChild(td)
}
table.appendChild(tr)
}
parent.appendChild(table)
}
let container = document.querySelector('.container')
tableInit(container, 7, 100)
let table = document.querySelector('table')
let td = document.getElementsByClassName('104')[0]
let cell = document.createElement('div')
cell.classList.add('cell')
cell.setAttribute('style',
`top: ${getPosition(td).top}px;
left: ${getPosition(td).left}px;
height: ${td.clientHeight + 2}px;
width: ${td.clientWidth * 2}px;`)
table.appendChild(cell)
.container {
overflow: auto;
width: 75%;
}
td {
border: 1px solid #000;
width: 40px;
height: 20px;
color: #fff;
}
.cell {
background-color: blue;
position: absolute;
z-index: 2;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div class="container"></div>
</body>
</html>
If you want the blue block to stay put in its position alongside the empty blocks, you need to make the container relative.
.container {
position: relative;
}

How to create a dynamic grid with even number of rows and columns?

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>

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>

Categories

Resources