This the code I wrote in order to find the answer to a programming challenge and it's to insert elements into a element with the values equal to color names and choosing a color form the list will change the color of the below it and it's supposed to be JS only. But my problem is that my code works perfectly on Firefox ,but it does not work in chrome or other browsers.
const color = [
"red",
"black",
"blue"
];
let select = document.getElementById("select");
for (let i = 0; i < color.length; i ) {
let container = document.createElement("option");
container.innerText = color[i];
container.value = color[i];
container.id = i 1;
select.append(container);
}
for (let j = 1; j <= color.length; j ) {
select[j].addEventListener("click", function colorChange() {
document.getElementById("box").style.backgroundColor = `${select[j].value}`;
});
}
#box {
width: 50px;
height: 50px;
border: 1px solid green;
}
<!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>Test</title>
</head>
<body>
<select name="" id="select">
<option value="">Choose a color</option>
</select>
<div id="box">
</div>
<script src="script.js">
</script>
</body>
</html>
CodePudding user response:
Well good news, this isn't because of JavaScript is disabled on the browser. I tried running your code against Firefox and Vivaldi and it seems that Vivaldi, Google Chrome, and other Chromium-based web browsers ignored your request to insert an event trigger. I mean this part of your code:
for (let j = 1; j <= color.length; j ) {
select[j].addEventListener("click", function colorChange() {
document.getElementById("box").style.backgroundColor = `${select[j].value}`;
});
}
I don't know which one is correct: whether event triggers can be added inside the <option>
tags inside a <select>
or not. I might want to forward this issue to my team over Webcompat.com.
Since you have already assigned the value
s for each <option>
(see container.value = color[i];
), you don't actually need to add these event triggers for each of the <option>
s. Instead, you can place the trigger directly inside the <select>
element, replacing your second loop into this:
select.addEventListener("click", function colorChange() {
document.getElementById("box").style.backgroundColor = select.value;
});
So the overall code would look like this:
const color = [
"red",
"black",
"blue"
];
let select = document.getElementById("select");
for (let i = 0; i < color.length; i ) {
let container = document.createElement("option");
container.innerText = color[i];
container.value = color[i];
container.id = i 1;
select.append(container);
}
for (let j = 1; j <= color.length; j ) {
select[j].addEventListener("click", function colorChange() {
document.getElementById("box").style.backgroundColor = `${select[j].value}`;
});
}
select.addEventListener("click", function colorChange() {
document.getElementById("box").style.backgroundColor = select.value;
});
Edit: using the change
listener instead of click
would be a better idea since the colorChange()
function will only be executed if the dropdown value has been changed. Thanks to pyb for pointing this out.
Update: I have forwarded this to https://github.com/webcompat/web-bugs/issues/97662.
CodePudding user response:
When the code works in a single browser ant not in the rest, it's an indicator that your code isn't written properly. The fact that it runs in Firefox makes some sense, because this browser usually supports experimental options that are not yet supported globally.
Looking at your code, I found some issues, like declaring a function by name within event listener.
Setting a listener to an option element is counter productive in my opinion, so I changed it to a more standard/useful change
listener.
const color = [
"red",
"black",
"blue"
];
let select = document.getElementById("select");
for (let i = 0; i < color.length; i ) {
let container = document.createElement("option");
container.innerText = color[i];
container.value = color[i];
container.id = i 1;
select.append(container);
}
// Select an option will trigger the change event.
select.addEventListener("change", function() {
document.getElementById("box").style.backgroundColor = this.value;
});
#box {
width: 50px;
height: 50px;
border: 1px solid green;
}
<select name="" id="select">
<option value="">Choose a color</option>
</select>
<div id="box"></div>
CodePudding user response:
I got it working by making the following changes:
- Use one
change
event listener on the select - Refer to the selected
option
element asthis
- Change
`${select[j].value}`
tothis.value
in the event listener
<!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>Test</title>
</head>
<body>
<select name="" id="select">
<option value="">Choose a color</option>
</select>
<div id="box">
</div>
<script src="script.js">
</script>
</body>
</html>
const color = [
"red",
"black",
"blue"
];
let select = document.getElementById("select");
for (let i = 0; i < color.length; i ) {
let container = document.createElement("option");
container.innerText = color[i];
container.value = color[i];
container.id = i 1;
select.append(container);
}
select.addEventListener("change", function colorChange() {
document.getElementById("box").style.backgroundColor = this.value;
});
CodePudding user response:
It has something to do with how event bubbling for select/option is implemented in Firefox and other browsers.
Try this simple code:
document.querySelectorAll("option").forEach(item => item.addEventListener("click", () => {
console.log("clicked")
}))
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Test</title>
</head>
<body>
<select name="" id="select">
<option value="1">1</option>
<option value="2">2</option>
</select>
</body>
</html>
Firefox logs that it's clicked, while Chrome doesn't.
Or try this code:
document.querySelector("select").addEventListener("click", (e) => {
console.log(e.target)
})
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Test</title>
</head>
<body>
<select name="" id="select">
<option value="1">1</option>
<option value="2">2</option>
</select>
</body>
</html>
Firefox reports that option
was clicked, while Chrome reports that select
was clicked.
CodePudding user response:
If this works properly in Firefox might be in chrome JavaScript is disabled.