0

Here's a picture of my problem: enter image description here

I don't want to display all three of these pictures inside of my box when I click on them I want to display a different image when I click on a different button, but I don't know how to go about this. I was thinking about incorporating css into my javascript by using the display property whenever I click on a button, but I wasn't able to get that to work.

Here's my HTML code:

function player_1(src, width, height, alt) {
  var img = document.createElement("img");
  img.src = src;
  img.width = width;
  img.height = height;
  img.alt = alt;

  // This next line will just add it to the player_1 box
  document.getElementById("player_1").appendChild(img);
}

function player_2(src, width, height, alt) {
  var img = document.createElement("img");
  img.src = src;
  img.width = width;
  img.height = height;
  img.alt = alt;

  // This next line will just add it to the player_2 box
  document.getElementById("player_2").appendChild(img);
}

//functions for displaying images when clicking on player 1 icons
function rock_logo() {
  var src = "images/rock.png";
  player_1("images/rock.png", 60, 60, "rock");
}

function paper_logo() {
  var src = "images/my_paper.png"
  player_1("images/my_paper.png", 60, 60, "paper");
}

function scissors_logo() {
  var src = "images/scissors.png";
  player_1("images/scissors.png", 60, 60, "scissors");
}

//Functions for displaying images when clicking on player 2 icons
function player_2_rock() {
  var src = "images/rock.png";
  player_2("images/rock.png", 60, 60, "rock");
}

function player_2_paper() {
  var src = "images/my_paper.png";
  player_2("images/my_paper.png", 60, 60, "rock");
}

function player_2_scissors() {
  var src = "images/rock.png";
  player_2("images/rock.png", 60, 60, "rock");
}


//timer works properly now
const timerText = document.getElementById("timer");
const btnStart = document.getElementById("btn-start");

let count = 10;
let intervalId;


btnStart.addEventListener("click", function() {
  intervalId = setInterval(function() {
    count -= 1;
    timerText.textContent = count;
    if (count == 0) {
      clearInterval(intervalId);
    }
  }, 1000);
});
<h1>Rock, Paper, Scissors Game</h1>
<div id="button">
  <button id="btn-start">Press to start timer</button>
</div>
<div class="player_blocks">
  <div id="icon_1">
    <button class="btn-start" onclick="rock_logo();"><img src="images/rock.png" height="50px" width="50px"></button>
    <button class="btn-start" onclick="paper_logo();"><img src="images/my_paper.png" height="50px" width="50px"></button>
    <button class="btn-start" onclick="scissors_logo();"><img src="images/scissors.png" height="50px" width="50px"></button>
  </div>

  <div id="player_1_container">
    <div id="player_1"></div>
    <div id="counter_1">
      <div class="counter"></div>
      <div class="counter"></div>
      <div class="counter"></div>
    </div>
  </div>

  <div id="time">
    <p id="timer">10</p>
  </div>


  <div id="player_2_container">
    <div id="player_2"></div>
    <div id="counter_2">
      <div class="counter"></div>
      <div class="counter"></div>
      <div class="counter"></div>
    </div>

  </div>


  <div id="icon_2">
    <button class="btn-start" onclick="player_2_rock();"><img src="images/rock.png" height="50px" width="50px"></button>
    <button class="btn-start" onclick="player_2_paper()"><img src="images/my_paper.png" height="50px" width="50px"></button>
    <button class="btn-start" onclick="player_2_scissors()"><img src="images/scissors.png" height="50px" width="50px"></button>
  </div>
</div>

4
  • 1
    Remove everything that is not part of the problem. Reduce it to the bare minimum. Commented Aug 12, 2021 at 19:44
  • Your description is very difficult to follow. You've got like 5 lines of text and only one period. Please clarify your thoughts. Also, please use the code snippet button to make runnable code. Commented Aug 12, 2021 at 19:47
  • What else do you want me to say? I think everyone understands what it is that I need done. Plus I added punctuation to my description so it's easy for people to understand and there is more than one period btw. @I wrestled a bear once. Commented Aug 12, 2021 at 20:52
  • I thought I needed to use all of the code from my HTML so you could see where the div's came from when you looked at my JavaScript code, but your right about me not needing to use all my JavaScript code. @wazz Commented Aug 12, 2021 at 21:02

3 Answers 3

2

You can replace your function

function player_2(src, width, height, alt) {
  var img = document.createElement("img");
  img.src = src;
  img.width = width;
  img.height = height;
  img.alt = alt;

  // This next line will just add it to the player_2 box
  document.getElementById("player_2").appendChild(img);
}

by something like this:

function player_2(src, width, height, alt) {
  //get the div and look if img exists
  let div = document.querySelector("#player_2");
  let img = div.querySelector("img");

  if (img == null) {
    //if not exists,create it and append, otherwise it'll re-use existing one
    img = document.createElement("img");
    div.appendChild(img);
  }

  img.src = src;
  img.width = width;
  img.height = height;
  img.alt = alt;
}

Same thing must be done for player1 function

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

1 Comment

Thanks for showing me another way of going about it. I've never seen "querySelectors" before. I'm new to JavaScript. @Enzo Leonel
1

Instead of adding/removing images from the DOM, it's better control which image is visible via CSS:

function player_1(type) {
  document.getElementById("player_1").title = type;
}

function player_2(type) {
  document.getElementById("player_2").title = type;
}

//functions for displaying images when clicking on player 1 icons
function rock_logo() {
  player_1("rock");
}

function paper_logo() {
  player_1("paper");
}

function scissors_logo() {
  player_1("scissors");
}

//Functions for displaying images when clicking on player 2 icons
function player_2_rock() {
  player_2("rock");
}

function player_2_paper() {
  player_2("paper");
}

function player_2_scissors() {
  player_2("scissors");
}


//timer works properly now
const timerText = document.getElementById("timer");
const btnStart = document.getElementById("btn-start");

let count = 10;
let intervalId;


btnStart.addEventListener("click", function() {
  intervalId = setInterval(function() {
    count -= 1;
    timerText.textContent = count;
    if (count == 0) {
      clearInterval(intervalId);
    }
  }, 1000);
});
.pick
{
  background-repeat: no-repeat;
  background-position: center;
  width: 0;
  height: 0;
}

.pick[title]
{
  width: 50px;
  height: 50px;
}
.pick[title="rock"]
{
  background-image: url("https://svgshare.com/i/_8h.svg");
}
.pick[title="paper"]
{
  background-image: url("https://svgshare.com/i/_9g.svg");
}
.pick[title="scissors"]
{
  background-image: url("https://svgshare.com/i/_9X.svg");
}


/* ignore this */

img[src="images/my_paper.png"]
{
  background-image: url("https://svgshare.com/i/_9g.svg");

  background-repeat: no-repeat;
  background-position: center;
}

img[src="images/rock.png"]
{
  background-image: url("https://svgshare.com/i/_8h.svg");

  background-repeat: no-repeat;
  background-position: center;
}

img[src="images/scissors.png"]
{
  background-image: url("https://svgshare.com/i/_9X.svg");

  background-repeat: no-repeat;
  background-position: center;
}
<h1>Rock, Paper, Scissors Game</h1>
<div id="button">
  <button id="btn-start">Press to start timer</button>
</div>
<div class="player_blocks">
  <div id="icon_1">
    <button class="btn-start" onclick="rock_logo();"><img src="images/rock.png" height="50px" width="50px"></button>
    <button class="btn-start" onclick="paper_logo();"><img src="images/my_paper.png" height="50px" width="50px"></button>
    <button class="btn-start" onclick="scissors_logo();"><img src="images/scissors.png" height="50px" width="50px"></button>
  </div>

  <div id="player_1_container">
    <div id="player_1" class="pick"></div>
    <div id="counter_1">
      <div class="counter"></div>
      <div class="counter"></div>
      <div class="counter"></div>
    </div>
  </div>

  <div id="time">
    <p id="timer">10</p>
  </div>


  <div id="player_2_container">
    <div id="player_2" class="pick"></div>
    <div id="counter_2">
      <div class="counter"></div>
      <div class="counter"></div>
      <div class="counter"></div>
    </div>
  </div>


  <div id="icon_2">
    <button class="btn-start" onclick="player_2_rock();"><img src="images/rock.png" height="50px" width="50px"></button>
    <button class="btn-start" onclick="player_2_paper()"><img src="images/my_paper.png" height="50px" width="50px"></button>
    <button class="btn-start" onclick="player_2_scissors()"><img src="images/scissors.png" height="50px" width="50px"></button>
  </div>
</div>

2 Comments

Thanks for the advice. I will do that from now on. @vanowm
I've updated example, by removing images from HTML and instead displaying appropriate image as a background image inside the div
0

It is generally considered good practice to leave all elements in place and don't change styling or image src dynamically, but instead simply add and remove css classes to get the effect you want.

Let's consider the following html:

<div class="imageContainer showRock">
    <div class="image rock"></div>
    <div class="image paper"></div>
    <div class="image scissors"></div>
</div>

How could I get the above html to show the rock icon, but just by changing showRock to showPaper orshowScissors it shows the paper icon or scissors icon instead?

<div class="imageContainer showPaper">
    <div class="image rock"></div>
    <div class="image paper"></div>
    <div class="image scissors"></div>
</div>

Here is some css that can do this:

/* An image container wraps some images */
.imageContainer {
    display: block;
}

/* all images within image containers are hidden by default */
.imageContainer .image {
    display: none;
    width: 60px;
    height: 60px;
}

/* The rock image hass an additional css class 'rock' and even though it is hidden, we still know what background it will have. */
.image.rock {
    background: url(images/my_paper.png)
}

.image.paper {
    background: url(images/my_paper.png)
}

.image.scissors {
    background: url(images/my_paper.png)
}

/* To show rock, we simply add the showRock css class to the imageContainer */
.imageContainer.showRock .image.rock {
    display: block;
}

/* To show paper, we simply add the showPaper css class to the imageContainer*/
.imageContainer.showPaper .image.rock {
    display: block;
}

/* to show scissors, we simply add the showScissors css class to the imageContainer*/
.imageContainer.showScissors .image.rock {
    display: block;
}

All we need to do is change the css class on the image container and bam we have the image we want. But how do we wire it up and actually make it work when clicking buttons. Let's consider the following html:

<div id="icon_1" class="iconContainer">
    <button class="chooseButton" data-action="imageContainer showRock"><img src="images/rock.png" height="50px" width="50px"></button>
    <button class="chooseButton" data-action="imageContainer showPaper"><img src="images/my_paper.png" height="50px"
            width="50px"></button>
    <button class="chooseButton" data-action="imageContainer showScissors"><img src="images/scissors.png" height="50px"
            width="50px"></button>
</div>

<div id="player_1_container" class="playerContainer">
    <div id="player_1"></div>
    <div class="imageContainer">
        <div class="image rock"></div>
        <div class="image paper"></div>
        <div class="image scissors"></div>
    </div>
</div>

When we click a chooseButton, we want to get the data-action attribute value, and apply it to the image container's css class.

function setupPlayer(playerIconsId, playerContainerId) {
    const playerIcons = document.getElementById(playerIconsId);
    const playerContainer = document.getElementById(playerContainerId);

    // find the image container within the player container
    const playerImageContainer = playerContainer.querySelector('.imageContainer');

    // For each button, wire up the click event, get its data-action attribute, and apply it to the imageContainer
    playerIcons.querySelectorAll('.chooseButton').forEach(function(button) {
        button.addEventListener("click", function(event) {
            event.preventDefault();
            playerImageContainer.setAttribute('class', event.target.dataset.action);
        }, false);
    });
}

Now we simply set up player 1:

setupPlayer("icon_1", "player_1_container");

Also for the timer, it's generally good practice to use setTimeout, and if you need to run it again, call it again, if not, then don't that way you don't need to keep track of the interval id.

I also added click prevention when the timer is active. Assuming you don't want your timer resetting while it's already counting down.

let TimeIsUp = function() {
    // Do something when time runs out
}

/**
 * Initialize the timer functionality
 */
(function(startButtonId, timerId, numTicks, onComplete) {
    const btnStart = document.getElementById(startButtonId);
    const timerText = document.getElementById(timerId);
    let isActive = false;

    let timerStart = function() {
        isActive = true;
        let count = numTicks;
        let timerTick = function() {
            timerText.textContent = count;
            if(count == 0) {

                onComplete();
                isActive = false;
                return;
            }
            count--;
            window.setTimeout(timerTick, 1000);
        }
        timerTick();
    };

    btnStart.addEventListener("click", function(evt) { 
        evt.preventDefault();
        if(!isActive) {
            timerStart();
        }
    }, false);
})("btn-start", "timer", 10, TimeIsUp);

1 Comment

What's wrong with making img src dynamically? what could happen? @TxRegex

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.