trying to show re render the page when i click on the show details button - javascript

Hello guys i am new to this i am trying to re render my page any time i click on the show details buttons so i can show the name, height and gender of the sky wars characters i have tried initializing a variable to false and on click i tried changing the value to true but it did not work. please here is my code.
const containerEl = document.getElementById("container");
const list = document.createDocumentFragment();
const images = [
"https://oyster.ignimgs.com/mediawiki/apis.ign.com/star-wars-episode-7/2/2d/Luke.jpg?width=1280",
"https://images.immediate.co.uk/production/volatile/sites/3/2019/10/EP9-FF-001686-336e75b.jpg?quality=90&resize=980,654",
"https://hips.hearstapps.com/digitalspyuk.cdnds.net/17/07/1487160686-r2-d2.jpg",
"https://lumiere-a.akamaihd.net/v1/images/darth-vader-main_4560aff7.jpeg?region=0%2C67%2C1280%2C720",
"https://www.costumerealm.com/wp-content/uploads/2019/12/51G4Jox9MlL._SX466_.jpg",
"https://static.wikia.nocookie.net/starwars/images/e/eb/OwenCardTrader.png/revision/latest?cb=20171108050140",
"https://static.wikia.nocookie.net/fanmade-works/images/8/8d/Beru_Lars.png/revision/latest/scale-to-width/360?cb=20200317025929",
"https://static.wikia.nocookie.net/star-wars-canon-extended/images/2/23/R5.jpg/revision/latest?cb=20160123232521",
"https://static.wikia.nocookie.net/starwars/images/0/00/BiggsHS-ANH.png/revision/latest?cb=20130305010406",
"https://media.gq.com/photos/622919842677fb88bf480855/16:9/w_2143,h_1205,c_limit/Screen%20Shot%202022-03-09%20at%204.15.50%20PM.png"
]
const getData = async () => {
const res = await fetch("https://swapi.dev/api/people");
const resData = await res.json();
const result = resData.results;
console.log(result)
main(result)
}
getData();
const main = (data) => {
let isVisible = false;
containerEl.innerHTML = "";
data.map(({ gender, height, name }, i) => {
const starWars = `
<img class="images" src=${images[i]}/>
<button id="btn" class="btn">Show Details</button>
<h1 class="starwars">${isVisible ? name : ""}</h1>
<h3>${isVisible ? gender : ""}</h3>
<h3>${isVisible ? height : ""}</h3>
`;
const item = document.createElement("div");
item.classList.add("items")
item.innerHTML = starWars
const btn = item.querySelector(".btn");
btn.addEventListener("click", () => {
isVisible = true
})
list.appendChild(item)
})
containerEl.append(list)
}
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="stylesheet" href="./style/index.css" >
<title>Star Wars</title>
</head>
<body>
<!-- Write your implementation here -->
<div id="container" class="container">
</div>
<script src="./script/index.js"></script>
</body>
</html>

This approach is not possible. The string literals, such as ${isVisible ? name : ""} are evaluated at the time that your template item is created, so since you've set the isVisible is false, it will only ever produce an empty string.
Instead, generate your string template with the values and then use a class to toggle the visibility of the details.
const containerEl = document.getElementById("container");
const images = [
"https://oyster.ignimgs.com/mediawiki/apis.ign.com/star-wars-episode-7/2/2d/Luke.jpg?width=1280",
"https://images.immediate.co.uk/production/volatile/sites/3/2019/10/EP9-FF-001686-336e75b.jpg?quality=90&resize=980,654",
"https://hips.hearstapps.com/digitalspyuk.cdnds.net/17/07/1487160686-r2-d2.jpg",
"https://lumiere-a.akamaihd.net/v1/images/darth-vader-main_4560aff7.jpeg?region=0%2C67%2C1280%2C720",
"https://www.costumerealm.com/wp-content/uploads/2019/12/51G4Jox9MlL._SX466_.jpg",
"https://static.wikia.nocookie.net/starwars/images/e/eb/OwenCardTrader.png/revision/latest?cb=20171108050140",
"https://static.wikia.nocookie.net/fanmade-works/images/8/8d/Beru_Lars.png/revision/latest/scale-to-width/360?cb=20200317025929",
"https://static.wikia.nocookie.net/star-wars-canon-extended/images/2/23/R5.jpg/revision/latest?cb=20160123232521",
"https://static.wikia.nocookie.net/starwars/images/0/00/BiggsHS-ANH.png/revision/latest?cb=20130305010406",
"https://media.gq.com/photos/622919842677fb88bf480855/16:9/w_2143,h_1205,c_limit/Screen%20Shot%202022-03-09%20at%204.15.50%20PM.png"
]
async function getData () {
const res = await fetch("https://swapi.dev/api/people");
const resData = await res.json();
return resData.results;
}
async function main () {
const data = await getData();
containerEl.innerHTML = "";
const list = document.createElement("ul")
data.map(({ gender, height, name }, i) => {
const starWars = `
<img class="images" src=${images[i]}/>
<button id="btn" class="btn">Show Details</button>
<div class="details">
<h2 class="starwars">${name}</h2>
<h3>${gender}</h3>
<h3>${height}</h3>
</div>
`;
const item = document.createElement("li");
item.classList.add("item", "hidden")
item.innerHTML = starWars
const btn = item.querySelector(".btn");
btn.addEventListener("click", toggleVisibility)
list.appendChild(item)
})
containerEl.append(list)
}
main()
function toggleVisibility(event) {
const el = event.target.closest('.item')
el.classList.toggle("hidden")
}
img {
width: 100%;
}
ul {
padding: 0;
margin: 0;
list-style-type: none;
display: grid;
gap: 1rem;
}
li {
border: 2px solid #ccc;
border-radius: .5rem;
overflow: hidden;
}
button {
font-weight: bold;
border: 0;
background-color: #222;
padding: .5rem .75rem;
color: white;
}
.item {
display: grid;
width: 25rem;
margin: auto;
}
.details {
padding: 1rem;
}
.hidden .details {
display: none;
}
<div id="container" class="container"></div>

Related

Can a function be inside another function?

I am working on a library project but my function called changeColor inside the readStatus function does not appear to be working.
I've tried separating it but having two event listeners on the same button does not appear to work. My goal is for readStatus function to allow a user to update the status of a book from no to yes when finished with the book.
Likewise, I want to change the background color of the div (class: card) when yes to be green and no to be red.
Can anyone tell me what I'm doing wrong?
let myLibrary = [];
function Book(title, author, pages, read) {
this.title = title;
this.author = author;
this.pages = pages;
this.read = read;
}
function addBookToLibrary(title, author, pages, read) {
let book = new Book(title, author, pages, read);
myLibrary.push(book);
displayOnPage();
}
function displayOnPage() {
const books = document.querySelector(".books");
const removeDivs = document.querySelectorAll(".card");
for (let i = 0; i < removeDivs.length; i++) {
removeDivs[i].remove();
}
let index = 0;
myLibrary.forEach((myLibrarys) => {
let card = document.createElement("div");
card.classList.add("card");
books.appendChild(card);
for (let key in myLibrarys) {
let para = document.createElement("p");
para.textContent = `${key}: ${myLibrarys[key]}`;
card.appendChild(para);
}
let read_button = document.createElement("button");
read_button.classList.add("read_button");
read_button.textContent = "Read ";
read_button.dataset.linkedArray = index;
card.appendChild(read_button);
read_button.addEventListener("click", readStatus);
let delete_button = document.createElement("button");
delete_button.classList.add("delete_button");
delete_button.textContent = "Remove";
delete_button.dataset.linkedArray = index;
card.appendChild(delete_button);
delete_button.addEventListener("click", removeFromLibrary);
function removeFromLibrary() {
let retrieveBookToRemove = delete_button.dataset.linkedArray;
myLibrary.splice(parseInt(retrieveBookToRemove), 1);
card.remove();
displayOnPage();
}
function readStatus() {
let retrieveBookToToggle = read_button.dataset.linkedArray;
Book.prototype = Object.create(Book.prototype);
const toggleBook = new Book();
if (myLibrary[parseInt(retrieveBookToToggle)].read == "yes") {
toggleBook.read = "no";
myLibrary[parseInt(retrieveBookToToggle)].read = toggleBook.read;
} else if (myLibrary[parseInt(retrieveBookToToggle)].read == "no") {
toggleBook.read = "yes";
myLibrary[parseInt(retrieveBookToToggle)].read = toggleBook.read;
}
let colorDiv = document.querySelector(".card");
function changeColor() {
for (let i = 0; i < length.myLibrary; i++) {
if (myLibrary[i].read == "yes") {
colorDiv.style.backgroundColor = "green";
} else if (myLibrary[i].read == "no") {
colorDiv.style.backgroundColor = "red";
}
}
}
displayOnPage();
}
index++;
});
}
let add_book = document.querySelector(".add-book");
add_book.addEventListener("click", popUpForm);
function popUpForm() {
document.getElementById("data-form").style.display = "block";
}
function closeForm() {
document.getElementById("data-form").style.display = "none";
}
let close_form_button = document.querySelector("#close-form");
close_form_button.addEventListener("click", closeForm);
function intakeFormData() {
let title = document.getElementById("title").value;
let author = document.getElementById("author").value;
let pages = document.getElementById("pages").value;
let read = document.getElementById("read").value;
if (title == "" || author == "" || pages == "" || read == "") {
return;
}
addBookToLibrary(title, author, pages, read);
document.getElementById("data-form").reset();
}
let submit_form = document.querySelector("#submit-form");
submit_form.addEventListener("click", function (event) {
event.preventDefault();
intakeFormData();
});
* {
margin: 0;
padding: 0;
background-color: rgb(245, 227, 205);
}
.books {
display: grid;
grid-template-columns: 1fr 1fr 1fr 1fr;
text-align: center;
margin: 20px;
gap: 10px;
}
.card {
border: 1px solid black;
border-radius: 15px;
padding: 10px;
}
.forms {
display: flex;
flex-direction: column;
align-items: center;
}
form {
margin-top: 20px;
}
select,
input[type="text"],
input[type="number"] {
width: 100%;
box-sizing: border-box;
}
.buttons-container {
display: flex;
margin-top: 10px;
}
.buttons-container button {
width: 100%;
margin: 2px;
}
.add-book {
margin-top: 20px;
}
#data-form {
display: none;
}
.read_button {
margin-right: 10px;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="stylesheet" href="style.css" />
<title>Document</title>
</head>
<body>
<div class="container">
<div class="forms">
<button class="add-book">Add Book To Library</button>
<div class="pop-up">
<form id="data-form">
<div class="form-container">
<label for="title">Title</label>
<input type="text" name="title" id="title" />
</div>
<div class="form-container">
<label for="author">Author</label>
<input type="text" name="author" id="author" />
</div>
<div class="form-container">
<label for="pages">Pages</label>
<input type="number" name="pages" id="pages" />
</div>
<div class="form-container">
<label for="read">Read</label>
<select name="read" id="read">
<option value="yes">Yes</option>
<option value="no">No</option>
</select>
</div>
<div class="buttons-container">
<button type="submit" id="submit-form">Submit Form</button>
<button type="button" id="close-form">Close Form</button>
</div>
</form>
</div>
</div>
<div class="books"></div>
</div>
<script src="script.js"></script>
</body>
</html>
A couple things needed.
First, you should put the readStatus and removeFromLibrary functions outside of the foreach loop.
Then I think you are wanting changeColor to run whenever readStatus is run. Either put the changeColor code directly inside the readStatus or put changeColor() inside readStatus.
I think you want the Book to not be a function but a class.

Unable to place an image using Javascript for a random image generator code

[image of a mole to be placed randomly in the squares created][1
**
I am trying to code the game called 'Whack-a-mole'. I created h1 and div elements to be placed on screen using javascript . Then I wanted to place an image inside the squares to appear randomly, but it does not appear in the squares. Could you please help me with where I went wrong ?
Thank You
. I add
// MY CODE
// const h1 = document.createElement('h1');
// h1.textContent = 'Your Score: ';
// h1.id = 'score';
// document.body.append(h1);
// const time = document.createElement('h1');
// time.textContent = 'Time Left: ';
// time.id = 'time';
// document.body.append(time);
// const grid = document.createElement('div');
// grid.className = 'grid';
// document.body.append(grid);
// for (let i = 0; i < 8; i++) {
// let square = document.createElement('img');
// square.className = 'square';
// square.id = ('data-id', i+1);
// grid.append(square);
// };
// const result = document.querySelector('#score');
// const left = document.querySelector('#time');
// const boxes = document.querySelectorAll('.square');
// const images = document.querySelector('.mole');
// function randomMole() {
// boxes.forEach(box => {
// box.classList.remove('images');
// });
// let randomSquare = boxes[Math.floor(Math.random() * 8)];
// randomSquare.classList.add('images');
// };
// randomMole();
// Ania code
const squares = document.querySelectorAll('.square')
const mole = document.querySelector('.mole')
const timeLeft = document.querySelector('#time-left')
const score = document.querySelector('#score')
let result = 0
let hitPosition
let currentTime = 60
let timerId = null
function randomSquare() {
squares.forEach(square => {
square.classList.remove('mole')
})
let randomSquare = squares[Math.floor(Math.random() * 9)]
randomSquare.classList.add('mole')
hitPosition = randomSquare.id
}
randomSquare();
squares.forEach(square => {
square.addEventListener('mousedown', () => {
if (square.id == hitPosition) {
result++
score.textContent = result
hitPosition = null
}
})
})
function moveMole() {
timerId = setInterval(randomSquare, 500)
}
moveMole()
function countDown() {
currentTime--
timeLeft.textContent = currentTime
if (currentTime == 0) {
clearInterval(countDownTimerId)
clearInterval(timerId)
alert('GAME OVER! Your final score is ' + result)
}
}
let countDownTimerId = setInterval(countDown, 1000)
.grid {
width: 600px;
height: 300px;
display: flex;
flex-wrap: wrap;
}
.square {
width: 135px;
height: 135px;
border: solid rgb(11, 8, 8) 1px;
}
.mole {
background-image: url('images/mole.jpg');
background-size: cover;
}
<!DOCTYPE html>
<html lang="en">
<head>
<title></title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="style.css" rel="stylesheet">
</head>
<body>
<h2>Your score:</h2>
<h2 id="score">0</h2>
<h2>Time Left:</h2>
<h2 id="time-left">60</h2>
<div class="grid">
<div class="square" id="1"></div>
<div class="square" id="2"></div>
<div class="square" id="3"></div>
<div class="square" id="4"></div>
<div class="square" id="5"></div>
<div class="square" id="6"></div>
<div class="square" id="7"></div>
<div class="square" id="8"></div>
<div class="square" id="9"></div>
</div>
<script src="Ania JS/Ania game 3.js"></script>
</body>
</html>
**
I suppose you need the .mole class to display the image. Here's a a minimal reproducable example for your code.
Play with it by forking this stackblitz project.
Or play the game itself 🙃
document.addEventListener(`click`, evt =>
evt.target.id === `redo` && randomMole());
document.body.insertAdjacentHTML(
`beforeend`, `<div class="grid">${
[...Array(8)].map((_, i) => `<img class="square" data-id=${i}>`)
.join(``) }</div>`);
document.querySelector(`#redo`).click();
function randomMole() {
const mole = document.querySelector(`.mole`);
mole && mole.classList.remove('mole');
document.querySelectorAll('.square')[Math.floor(Math.random() * 8)]
.classList.add(`mole`);
};
.grid {
width: 600px;
height: 300px;
display: flex;
flex-wrap: wrap;
}
.square {
width: 64px;
height: 64px;
border: solid rgb(11, 8, 8) 1px;
margin-right: 2px;
}
.mole {
background-image: url('//cdn.pixabay.com/photo/2012/05/02/17/24/ground-45742_960_720.png');
background-size: cover;
}
<p><button id="redo">random mole position</button></p>

Setting strict grid size in CSS grid

I am currently trying to complete an etch-a-sketch project but am having issues with setting a grid to respect a strict size value. I want to set it so that the grid squares become smaller and the overall container remains the same however what I currently have forces the grid to go off the page.
I have tried max-height and max-width settings but these don't seem to do anything. Could someone please help me ?
Javascript Code
const button16 = document.querySelector('.smol');
const button24 = document.querySelector('.med');
const button64 = document.querySelector('.large');
const button = document.querySelector('.reset');
const container = document.querySelector('.container');
function row(num, columns){
for (let i = 0; i < num; i++){
const div = document.createElement('div')
container.appendChild(div);
for (let i = 0; i < columns; i++){
const div2 = document.createElement('div2', );
div.appendChild(div2);
}
}
}
hover(row(16, 16))
button16.addEventListener('click', () => {
clearGrid();
hover(row(16, 16))
});
button24.addEventListener('click', () => {
clearGrid();
hover(row(24, 24))
});
button64.addEventListener('click', () => {
clearGrid();
hover(row(64, 64))
});
function hover() {
const wrapper2 = container.querySelectorAll('div2');
wrapper2.forEach(wrapper2 => wrapper2.addEventListener('mouseenter', () => {
const hash = '#';
let randomColor = Math.floor(Math.random()*16777215).toString(16);
wrapper2.style.backgroundColor = hash + randomColor;
}));
wrapper2.forEach(wrapper2 => button.addEventListener("click", () => {
wrapper2.style.backgroundColor = 'white';
}));
}
function clearGrid() {
container.innerHTML = null
}
My CSS
.container {
display: grid;
grid-template-columns:repeat(64, 1fr);
width: 500px;
height: 500px;
}
div2 {
border: solid 0.1px;
color: #424242;
display: grid;
width:30px;
height: 25px;
box-sizing: border-box
}
.buttonbox {
display: flex;
width: 500px;
}
.reset, .smol, .med, .large {
padding: 5px;
}
My html
<!DOCTYPE HTML>
<html lan="en">
<head>
<meta charset = utf-8>
<link rel= 'stylesheet' href="Styles.css" ></script>
<script src = GameLogic.js defer></script>
<title>My Etch-A-Sketch Project</title>
</head>
<body>
<h1>Etch-A-Sketch</h1>
<div class = "container">
</div>
<div class = 'buttonbox'>
<button class="reset">
Clear Grid
</button>
<button class="smol">
16 x 16
</button>
<button class="med">
24 x 24
</button>
<button class="large">
64 x 64
</button>
</div>
</body>
</html>

how to reset color grid?

I am creating a simple etch-a-sketch game. currently on hover it colors in black. I am trying to use a button to reset the colors back to white. However, i can't get the button to function with an event listener, if i add an alert it displays the alert but nothing else. Please guide me and supply a documentation that I can reference as I want to learn and fixing it without explaining will be counterproductive at this point.
Thank you !
const containerGrid = document.getElementById("mainGrid");
function makeGrid(col) {
for (let i = 0; i < col * col; i++) {
const gridAdd = document.createElement("div");
gridAdd.classList.add("box");
gridAdd.textContent = "";
containerGrid.appendChild(gridAdd);
}
}
makeGrid(16); // make grid 16*16
const btnClear = document.getElementById("clear");
//mouseover event black - need to link to button (well done :)
const boxes = document.querySelectorAll('.box').forEach(item => {
item.addEventListener('mouseover', event => {
item.style.backgroundColor = "black";
})
});
btnClear.addEventListener("click", () => {
boxes.style.backgroundColor = "white";
});
const changeGrid = document.getElementById(".sizechange");
/*clearBtn.forEach.addEventListener("click", function () {
clearBtn.style.color ="white";
});
*/
/*const randomBtn = document.getElementById("randomgen").addEventListener('click',(e) => {
console.log(this.classname)
console.log(e.currentTarget === this)
}) */
//change color
#mainGrid {
display: grid;
justify-content: center;
align-items: center;
grid-template-columns: repeat(16, 1fr);
grid-template-rows: auto;
margin-left: 150px;
width: 200px;
}
.box {
color: black;
border: 3px solid;
height: 10px;
width: 10px;
}
<!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>Etch-a-Sketch</title>
<link type="text/css" rel="stylesheet" href="styles.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
</head>
<body>
<div id="colorContainer">
<input type="radio" id="blackchoice" value="color" name="black" class="defaultbtn">
<label for="defaultcolor">black</label>
<input type="radio" id="randomgen" class="hey">
<label for="randomchoice">random</label>
</div>
<div id="changeGrid">
<button id="clear">clear</button>
</div>
<div id="mainGrid"></div>
<script src="app.js"></script>
</body>
</html>
A couple of related problems:
The variable boxes is undefined. It looks as though it was required to be the set elements with class box. When it is being defined this is indeed done, but then made undefined by the forEach attached to it. Separate out these two things and boxes will become the collection of all elements with class box.
Then when the clear is clicked you need to step through each of these boxes making their background color white, so again use a forEach.
<!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>Etch-a-Sketch</title>
<link type="text/css" rel="stylesheet" href="styles.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<style>
#mainGrid {
display: grid;
justify-content: center;
align-items: center;
grid-template-columns: repeat(16, 1fr);
grid-template-rows: auto;
margin-left: 150px;
width: 200px;
}
.box {
color: black;
border: 3px solid;
height: 10px;
width: 10px;
}
</style>
</head>
<body>
<div id="colorContainer">
<input type="radio" id="blackchoice" value="color" name="black" class="defaultbtn">
<label for="defaultcolor">black</label>
<input type="radio" id="randomgen" class="hey">
<label for="randomchoice">random</label>
</div>
<div id="changeGrid">
<button id="clear">clear</button>
</div>
<div id="mainGrid"></div>
<script src="app.js"></script>
<script>
const containerGrid = document.getElementById("mainGrid");
function makeGrid(col) {
for (let i = 0; i < col * col; i++) {
const gridAdd = document.createElement("div");
gridAdd.classList.add("box");
gridAdd.textContent = "";
containerGrid.appendChild(gridAdd);
}
}
makeGrid(16); // make grid 16*16
const btnClear = document.getElementById("clear");
//mouseover event black - need to link to button (well done :)
const boxes = document.querySelectorAll('.box');
boxes.forEach(box => {
box.addEventListener('mouseover', event => {
box.style.backgroundColor = "black";
})
});
btnClear.addEventListener("click", () => {
boxes.forEach(box => {
box.style.backgroundColor = "white";
});
});
const changeGrid = document.getElementById(".sizechange");
/*clearBtn.forEach.addEventListener("click", function () {
clearBtn.style.color ="white";
});
*/
/*const randomBtn = document.getElementById("randomgen").addEventListener('click',(e) => {
console.log(this.classname)
console.log(e.currentTarget === this)
}) */
//change color
</script>
</body>
</html>
Simplify your CSS
Use a SELECT element for your colors
Define the gridTemplateColumns in JS, not in CSS.
Use simpler functions
Use global variables to store the current grid size and color
Don't forget to clear your grid before changing the size
Assign the mouseenter Event on each cell on creation!
Add a boolean variable isPenDown for a better user experience!
const NewEL = (sel, prop) => Object.assign(document.createElement(sel), prop);
const EL_grid = document.querySelector("#grid");
const EL_clear = document.querySelector("#clear");
const EL_color = document.querySelector("[name=color]");
const EL_size = document.querySelector("[name=size]");
let size = parseInt(EL_size.value, 10);
let color = "black";
let isPenDown = false;
function makeGrid() {
EL_grid.innerHTML = ""; // Clear current grid!
for (let i = 0; i < size ** 2; i++) {
EL_grid.style.gridTemplateColumns = `repeat(${size}, 1fr)`;
EL_grid.append(NewEL("div", {
className: "box",
onmousedown() { isPenDown = true; paint(this); },
onmouseup() { isPenDown = false; },
onmouseenter() { if (isPenDown) paint(this); },
}));
}
};
function paint(EL) {
EL.style.backgroundColor = color;
}
EL_clear.addEventListener("click", () => {
const tmp_color = color; // Remember current color
color = "transparent"; // Temporarily set it to transparent
EL_grid.querySelectorAll(".box").forEach(paint); // Paint all cells as transparent
color = tmp_color; //* Reset as it was before.
});
EL_color.addEventListener("change", () => {
color = EL_color.value;
if (color === "random") color = `hsl(${~~(Math.random() * 360)}, 80%, 50%)`;
});
EL_size.addEventListener("change", () => {
size = parseInt(EL_size.value, 10);
makeGrid();
});
// INIT!
makeGrid();
#grid {
display: inline-grid;
margin: 10px 0;
}
#grid .box {
border: 1px solid;
height: 10px;
width: 10px;
margin: 0;
user-select: none;
}
<div>
<label>
Size:
<input type="number" name="size" value="16">
</label>
<label>
Color:
<select name="color">
<option value="black">black</option>
<option value="white">white</option>
<option value="red">red</option>
<option value="yellow">yellow</option>
<option value="orange">orange</option>
<option value="fuchsia">fuchsia</option>
<option value="transparent">CLEAR (transparent)</option>
<option value="random">RANDOM COLOR</option>
</select>
</label>
<button id="clear">Clear canvas</button>
</div>
<div id="grid"></div>

refactoring javascript code to create for loop

I am practicing Javascript. I want each link to display something different in the DOM when clicked.
Here is my current Javascript that works.
//used a 'for' loop to hide each 'notes' page
const element = document.querySelectorAll(".notes");
for (let x = 0; x < element.length; x++)
element[x].style.display = 'none';
const html_link= document.getElementById('html-link');
const css_link = document.getElementById('css-link');
const javascript_link = document.getElementById('js-link');
const html_notes = document.getElementById('html-notes');
const css_notes = document.getElementById('css-notes');
const js_notes = document.getElementById('js-notes');
html_link.onclick = function() {
html_notes.style.display = "block";
css_notes.style.display = "none";
js_notes.style.display = "none";
}
css_link.onclick = function() {
css_notes.style.display = "block";
html_notes.style.display = "none";
js_notes.style.display = "none";
}
javascript_link.onclick = () => {
js_notes.style.display = "block";
html_notes.style.display = "none";
css_notes.style.display = "none";
}
How can I refactor it using a for loop? My thinking was for each link clicked, display notes. But I am struggling to figure out how to display the notes div correctly that matches the link clicked. This is what I have started.
const links = document.querySelectorAll('.links')
for (const link of links) {
link.addEventListener('click', function() {
let ref = event.target.parentElement.id.replace('link','notes');
//replaces parent element with id 'notes'
const show = document.getElementById(ref);
//'show' div with new id
})
}
Welcome, fellow newbie! I've taken the liberty of writing the html and very minimal styling as well. This is my first attempt at an answer on stackoverflow.
Please note some features of the code I've added:
'links' class added to all links.
'notes' class added to all notes.
'data-notes' attribute added to all links (with the id of each link's respective notes)
<!DOCTYPE html>
<html dir="ltr" lang="en-US">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1.0"/>
</head>
<body>
<div class="outer">
<div id="html-link" data-notes="html-notes" class="links">
<p>html-link</p>
</div>
<div id="css-link" data-notes="css-notes" class="links">
<p>css-link</p>
</div>
<div id="javascript-link" data-notes="javascript-notes" class="links">
<p>javascript-link</p>
</div>
</div>
<div class="outer">
<div id="html-notes" class="notes">
<p>html-notes</p>
</div>
<div id="css-notes" class="notes">
<p>css-notes</p>
</div>
<div id="javascript-notes" class="notes">
<p>javascript-notes</p>
</div>
</div>
<style>
.links {
cursor: pointer;
background: green;
color: white;
padding: 1rem;
margin: 1rem;
}
.notes {
display: none;
background: blue;
color: white;
padding: 1rem;
margin: 1rem;
}
.outer {
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-around;
margin: 2rem 0;
}
</style>
<script>
const links = document.querySelectorAll('.links');
const notes = document.querySelectorAll('.notes');
for (const link of links) {
link.onclick = function () {
for (const note of notes) {
if (note.id == link.dataset.notes) {
note.style.display = "block";
} else {
note.style.display = "none";
}
}
}
}
</script>
</body>
</html>

Categories