Search code examples
javascriptif-statementbackground-image

How to change background image


I am a beginner in JS and am trying to create a simple function where I click on a button and the background image changes but it doesn't work (I was trying to recreate a simpler image slider). I can't understand why.

This is my JS. I have used the absolute link hoping it could fix the problem and the alert to see whether the if/else statement was working.

const btnLeft = document.getElementById("btn-left");
const btnRight = document.getElementById("btn-right");

btnLeft.addEventListener("click", whenClicked);
btnRight.addEventListener("click", whenClicked);

function whenClicked() {
if (btnLeft.clicked) {
document.getElementById("img2").style.backgroundImage = 
"url('https://images.unsplash.com/photo-1494783367193-149034c05e8f?ixlib=rb- 
1.2.1&q=80&fm=jpg&crop=entropy&cs=tinysrgb&dl=diego-jimenez-A-NVHPka9Rk-unsplash.jpg')";
} else alert("no click!");

}

This is my HTML:

<div class="slide-container">

    <div class="slide" id="img1">
       <button id="btn-left"> <i class="fas fa-arrow-circle-left fa-3x " ></i></button>
        <button id="btn-right"><i class="fas fa-arrow-circle-right fa-3x " ></i></button>
    </div>

    <div class="slide" id="img2">

    </div>

</div>

This is the relevant CSS.

 .slide-container {
display: flex;  
 }

.slide:nth-child(1) {
background-image: url(../img/img1.jpg);
height: 789px;
width: 100%; 
flex-shrink: 0;
background-size: cover;
background-position: center;
background-repeat: no-repeat;
}

.slide:nth-child(2) {
background-image: url(../img/img2.jpg);
height: 789px;
width: 100%; 
flex-shrink: 0;
background-size: cover;
background-position: center;
background-repeat: no-repeat;
}

#btn-left {
position: absolute;
top: 400px;
}
#btn-right {
position: absolute;
left: 1380px;
top: 400px;
}

Any help is deeply appreciated, I have been going crazy for hours! Thanks.

EDIT. After David784's help, I now have this:

const btnLeft = document.getElementById("btn-left");
const btnRight = document.getElementById("btn-right");


btnLeft.addEventListener("click", whenClicked);
btnRight.addEventListener("click", whenClicked);

function whenClicked(e) {
if (e.currentTarget === btnLeft ) {
document.getElementById("img1").style.backgroundImage = 
"url('https://images.unsplash.com/photo-1494783367193-149034c05e8f? 
ixlib=rb-1.2.1&q=80&fm=jpg&crop=entropy&cs=tinysrgb&dl=diego-jimenez- 
A-NVHPka9Rk-unsplash.jpg')";
} 
else alert("no click!");
}

and it works. But then when I try to add the same for the right button, such as

function whenClicked(e) {
if (e.currentTarget === btnRight ) {
document.getElementById("img1").style.backgroundImage = 
"url('https://images.unsplash.com/photo-1494783367193-149034c05e8f? 
ixlib=rb-1.2.1&q=80&fm=jpg&crop=entropy&cs=tinysrgb&dl=diego- 
jimenez-A-NVHPka9Rk-unsplash.jpg')";
} 
else alert("no click!");
}

the left button stopped working. Why?


Solution

  • Your question makes it sound as if the backgroundImage part is where the problem is, but I can't seem to duplicate (see working snippet below).

    However I did have trouble with the if (btnLeft.clicked)...I'm not sure Element.clicked is a thing...at least I've never seen it before. When I changed it to e.currentTarget===btnLeft, it just worked. (See Event.currentTarget for more info).

    const btnLeft = document.getElementById("btn-left");
    const btnRight = document.getElementById("btn-right");
    
    btnLeft.addEventListener("click", whenClicked);
    btnRight.addEventListener("click", whenClicked);
    
    function whenClicked(e) {
      if (e.currentTarget === btnLeft) {
        document.getElementById("img2").style.backgroundImage =
          "url('https://images.unsplash.com/photo-1494783367193-149034c05e8f?ixlib=rb-1.2.1&q=80&fm=jpg&crop=entropy&cs=tinysrgb&dl=diego-jimenez-A-NVHPka9Rk-unsplash.jpg')";
      } else alert("no click!");
    
    }
    .slide-container {
      display: flex;
    }
    
    .slide:nth-child(1) {
      background-image: url(../img/img1.jpg);
      height: 789px;
      width: 100%;
      flex-shrink: 0;
      background-size: cover;
      background-position: center;
      background-repeat: no-repeat;
    }
    
    .slide:nth-child(2) {
      background-image: url(../img/img2.jpg);
      height: 789px;
      width: 100%;
      flex-shrink: 0;
      background-size: cover;
      background-position: center;
      background-repeat: no-repeat;
    }
    
    #btn-left {
      position: absolute;
      top: 400px;
    }
    
    #btn-right {
      position: absolute;
      left: 1380px;
      top: 400px;
    }
    <div class="slide-container">
    
      <div class="slide" id="img1">
        <button id="btn-left"> <i class="fas fa-arrow-circle-left fa-3x " >left</i></button>
        <button id="btn-right"><i class="fas fa-arrow-circle-right fa-3x " >right</i></button>
      </div>
    
      <div class="slide" id="img2">
    
      </div>
    
    </div>

    *Edit: to address the comment about CSS, this is addressed by CSS Specificity rules. Which states:

    Inline styles added to an element (e.g., style="font-weight: bold;") always overwrite any styles in external stylesheets, and thus can be thought of as having the highest specificity.

    When doing element.style.backgroundImage, this creates an inline style, which will override. (with the exception I think of !important rules, which you should almost never use anyway)

    To address the question about passing the event into the event handler: this is a very helpful tool when using events, called the event object

    e.target is incredibly useful when you want to set the same event handler on multiple elements and do something to all of them when an event occurs on them.

    So the event object can be named pretty much whatever you want. You could call it e, event, evnt, or whatever. But it will give you access to a lot of very useful information, like the target of the click, the x/y coordinates of the click, etc.

    Or in this case currentTarget, which is slightly different than target, gives us access to the element that the event handler is actually attached to. (here the target would most likely be the i tag inside the button tag).