2

Hi I am trying to make a traffic light using an array of pictures. I currently need to change the image path stated in css when a button is clicked so that the light's picture changes. So in this case the content.url() line of each class needs to be change when function is called by the button. The method I'm currently using is incorrect but I think it may help to help you understand.


<style>
#rect{
    height:550px;
    width:180px;
    border:1px solid #000;
}
.black1 {
  position: relative;
  top: 10px;
  left: 10px;
  content.url('black.png')
}
.black2 {
  position: relative;
  top: 20px;
  left: 10px;
  content.url('black.png')
}
.black3 {
  position: relative;
  top: 30px;
  left: 10px;
  content.url('black.png')
}
</style>

<Body>
<div id="rect">
<img class="black1" />
<img class="black2" />
<img class="black3" />
</div>

<script>
var x = ["black.png", "red.png", "orange.png",'green.png'];
var i = -1;
function change(){
    i++;
    if (i == 0){
    document.getElementByClass('black1').src=x[1];
    document.getElementByClass('black2').src=x[0];
    document.getElementByClass('black3').src=x[0];
    }

}
</script>
<button onclick = "change()">Change light</button>
</div>
</Body>
</html>
1
  • Personally, I am bigger on loading all images on the page statically and using style.display to show and hide them Commented Feb 14, 2022 at 20:21

2 Answers 2

1

I would separate your css classes in red, orange/yellow, green. Then you can work with the classList function. Bellow you will find a simple working example. Feel free to improve it.

let i = -1;

function change() {
  const tl = document.querySelectorAll('.light');  
  i++;    
  
  if (i == 0) {
    tl[0].classList.add('red')
  }
  if (i == 1) {
    tl[1].classList.add('yellow')
  }
  if (i == 2) {
    tl[2].classList.add('green')
  }  
  if (i == 3) {
    tl[2].classList.remove('green');
    tl[1].classList.remove('yellow');
    tl[0].classList.remove('red');
    i = -1;
  }
}
#rect{
    height:350px;
    width:120px;
    border:1px solid #000;  
}
img {
  height: 100px;
}

.light {
  position: relative;
  top: 10px;
  left: 10px;
  content: url(https://via.placeholder.com/150/000000);  
}

.red {
  content: url(https://via.placeholder.com/150/FF0000);  
}

.yellow {
  content: url(https://via.placeholder.com/150/FFFF00);
}

.green {
  content: url(https://via.placeholder.com/150/008000);  
}
<Body>
  
<div id="rect">
<img class="light" />
<img class="light" />
<img class="light" />
</div>

<script>

</script>
<button onclick = "change()">Change light</button>
</div>
</Body>
</html>

Sign up to request clarification or add additional context in comments.

4 Comments

Thank you for you time and effort!
@HakahaglaX You welcome! It was helpful, a +1Upvote would be very nice ;-) Thank you!
Sorry but I dont have enough reputation to do an +1 :(
@HakahaglaX thanks for feedback. i forgot! i upvoted ;-) now it would work. thank you very much!
0

To make your program work, I would make it look something like this:

  1. Get rid of content.url('black.png') in css
  2. Set default urls to your img tags that would be "black.png"
  3. Make working code:
const urls = ["black.png", "red.png", "orange.png",'green.png'];
let index = -1;
const imgs = ["black1", "black1", "black1"].map(className => document.getElementByClass(className));

function change(){
  index++;
  // will take rest of division,
  // for example 4 % 3 === 1, 5 % 3 === 2, 6 % 3 === 0
  const currentLight = index % 3;
  imgs.forEach((image, i) => {
    if (i === currentLight) {
      // current image should be active and we map it correct light urls
      // for example currentLight is 0, if will make it url[0] which is red
      image.src = urls[currentLight + 1];
    }
    else {
      // turn off the lights that are not equal to currentLight
      image.src = urls[0];
    }
  });
}

change(); // initial call to turn the red light on. If not called all lights will be off

Hope this is the behaviour that you were looking for.

But I wrote that you need to get rid of content: url and your question is about changing it. Basically JavaScript cannot modify classes (unless you dynamically generate them with JS from string, but this is a terrible idea). If you really want to use content: url(does not mean you should), you need to create 3 classes .red, .orange and .green with respective urls and toggle those classes with JS like you would do with toggling src's.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.