I just started school, and this is my first question ever asked on Stackoverflow, so I apologize up front regarding both formatting and wording of this question.
I want to change the border color of my div to a style I have already declared when I click on it. To show that this has been selected.
I have three divs with id="red/green/pink".
Now, is there a way to change this function to grab information from the div I clicked, so I dont have to write 3 (almost) identical functions?
.chosenBorder{
border: 3px solid gold;
}
<div id="red" onclick="newColor('red')">Red?</div>
<div id="green" onclick="newColor('green')">Green?</div>
<div id="pink" onclick="newColor('pink')">Pink?</div>
<div onclick="whatNow(changeBig)">Choose!</div>
<script>
let changeBig = "";
let chosenDiv = document.getElementById("body");
function newColor(thisColor) {
changeBig = thisColor;
// something that make this part dynamic.classList.toggle("chosenBorder");
}
function whatNow(changeBig) {
document.body.style.backgroundColor = changeBig;
}
</script>
CodePudding user response:
Since you already have an id
contains the name of color; get the advantage of it: and keep track of the selected color in your variable changeBig
.
let changeBig = "";
function newColor(div) {
// initial all divs to black
initialDivs();
div.style.borderColor = div.id;
changeBig = div.id;
}
function initialDivs() {
[...document.querySelectorAll('.mainDivs')].forEach(div => {
div.style.borderColor = 'black'
});
}
function whatNow() {
document.body.style.backgroundColor = changeBig;
}
.mainDivs {
padding: 10px;
margin: 10px;
border: 3px solid;
outline: 3px solid;
width: fit-content;
cursor: pointer;
}
<div id="red" onclick="newColor(this)">Red?</div>
<div id="green" onclick="newColor(this)">Green?</div>
<div id="pink" onclick="newColor(this)">Pink?</div>
<div onclick="whatNow()">Choose!</div>
CodePudding user response:
There are a few (modern) modifications you can make to simplify things.
Remove the inline JS.
Use CSS to store the style information.
Use data attributes to store the colour rather than the id.
Wrap the div elements (I've called them boxes here) in a containing element. This way you can use a technique called event delegation. By attaching one listener to the container you can have that listen to events from its child elements as they "bubble up" the DOM. When an event is caught it calls a function that 1) checks that the event is from a box element 2) retrieves the color from the element's dataset, and adds it to its
classList
along with anactive
class.
// Cache the elements
const boxes = document.querySelectorAll('.box');
const container = document.querySelector('.boxes');
const button = document.querySelector('button');
// Add a listener to the container which calls
// `handleClick` when it catches an event fired from one of
// its child elements, and a listener to the button to change
// the background
container.addEventListener('click', handleClick);
button.addEventListener('click', handleBackground);
function handleClick(e) {
// Check to see if the child element that fired
// the event has a box class
if (e.target.matches('.box')) {
// Remove the color and active classes from
// all the boxes
boxes.forEach(box => box.className = 'box');
// Destructure the color from its dataset, and
// add that to the class list of the clicked box
// along with an active class
const { color } = e.target.dataset;
e.target.classList.add(color, 'active');
}
}
function handleBackground() {
// Get the active box, get its color, and then assign
// that color to the body background
const active = document.querySelector('.box.active');
const { color } = active.dataset;
document.body.style.backgroundColor = color;
}
.boxes { display: flex; flex-direction: row; background-color: white; padding: 0.4em;}
.box { display: flex; justify-content: center; align-items: center; width: 50px; height: 50px; border: 2px solid #dfdfdf; margin-right: 0.25em; }
button { margin-top: 1em; }
button:hover { cursor: pointer; }
.box:hover { cursor: pointer; }
.red { border: 2px solid red; }
.green { border: 2px solid green; }
.pink { border: 2px solid pink; }
<div >
<div data-color="red">Red</div>
<div data-color="green">Green</div>
<div data-color="pink">Pink</div>
</div>
<button>Change background</button>