Search code examples
javascriptonclickgetelementbyidgetelementsbyclassname

From getElementById to getElementsByClassName and get same result?


Looking at the code below, you will notice when I click the arrow icons an "Added!" text will appear in green to the left, but in one spot only.

I want the "Added!" text to appear next to each arrow icon, for each icon that is clicked, without removing the fade/animations.

(Example: If I click the top arrow icon, text will appear and fade to the left of that only; if I click the middle arrow icon only, text appears and fades to the left of that icon only; if I click the bottom arrow icon, text appears and fades to the left of that icon only)

How can I achieve this? Do I need to change the ID elements to Class elements? (I am willing to use whatever code works as long as it keeps the fade/animations).

  function showAdded() {
    let message = document.getElementById('notification-text');

    if (message.classList.contains('noDisplay')) {
      message.classList.remove('noDisplay');
    }

    // message.classList.add('noDisplay');
    message.style.animation = 'none';
    message.offsetHeight;
    message.style.animation = null;
  }
  .shopping-cart-add-on {
    background-image: url("https://upload.wikimedia.org/wikipedia/commons/9/9e/Plus_symbol.svg");
    background-repeat: no-repeat;
    background-size: 29px 29px;
    background-position: center;
    background-color: #fff;
    border: 1px solid rgba(0, 0, 0, .1);
    border-radius: 24px;
    padding: 8px;
    cursor: pointer;
    position: relative;
    top: -25px;
    left: 124px;
    transition: all .3s;
  }

  #notification-text {
    position: absolute;
    text-wrap: nowrap;
    animation-name: msgSuccess;
    animation-duration: 1s;
    opacity: 0;
    transition-delay: 4ms;
    color: green;
  }

  .noDisplay {
    display: none;
  }

  @keyframes msgSuccess {
    50% {
      opacity: 1;
    }

    99% {
      opacity: 0;
    }

    100% {
      opacity: 0;
      display: none;
    }
  }
  <br>

  <div class="shopping-cart-add-on" onclick="showAdded()" style="height: 28px; width: 28px"></div>
  <div id="notification-text" class="noDisplay">Added!</div>
  </div>

  <br><br>

  <div class="shopping-cart-add-on" onclick="showAdded()" style="height: 28px; width: 28px"></div>
  <div id="notification-text" class="noDisplay">Added!</div>
  </div>

  <br><br>

  <div class="shopping-cart-add-on" onclick="showAdded()" style="height: 28px; width: 28px"></div>
  <div id="notification-text" class="noDisplay">Added!</div>
  </div>


Solution

  • Change from id="notification-text" to class="notification-text".

    Add a parameter to the showAdded() function to tell it which div you clicked on. Then you can find the nested notification-text element within that.

    You also had extra </div> tags that were ending the shopping-cart-add-on divs prematurely, instead of wrapping them around the notification divs.

    function showAdded(div) {
      let message = div.querySelector('.notification-text');
    
      message.classList.remove('noDisplay');
    
      // message.classList.add('noDisplay');
      message.style.animation = 'none';
      message.offsetHeight;
      message.style.animation = null;
    }
    .shopping-cart-add-on {
      background-image: url("https://upload.wikimedia.org/wikipedia/commons/9/9e/Plus_symbol.svg");
      background-repeat: no-repeat;
      background-size: 29px 29px;
      background-position: center;
      background-color: #fff;
      border: 1px solid rgba(0, 0, 0, .1);
      border-radius: 24px;
      padding: 8px;
      cursor: pointer;
      position: relative;
      top: -25px;
      left: 124px;
      transition: all .3s;
    }
    
    .notification-text {
      position: absolute;
      text-wrap: nowrap;
      animation-name: msgSuccess;
      animation-duration: 1s;
      opacity: 0;
      transition-delay: 4ms;
      color: green;
    }
    
    .noDisplay {
      display: none;
    }
    
    @keyframes msgSuccess {
      50% {
        opacity: 1;
      }
      99% {
        opacity: 0;
      }
      100% {
        opacity: 0;
        display: none;
      }
    }
    <br>
    
    <div class="shopping-cart-add-on" onclick="showAdded(this)" style="height: 28px; width: 28px">
      <div class="notification-text" class="noDisplay">Added!</div>
    </div>
    
    <br><br>
    
    <div class="shopping-cart-add-on" onclick="showAdded(this)" style="height: 28px; width: 28px">
      <div class="notification-text" class="noDisplay">Added!</div>
    </div>
    
    <br><br>
    
    <div class="shopping-cart-add-on" onclick="showAdded(this)" style="height: 28px; width: 28px">
      <div class="notification-text" class="noDisplay">Added!</div>
    </div>