Buttons in slider not working using javascript

Tags:



I am trying to make a slider for a list of products and I have placed a button on each side of the slider to slide the products. The problem I am facing is that it works fine when I press exactly at the buttons but when I press anywhere around it, it throws the error Uncaught TypeError: Cannot read property ‘style’ of null.

next = (target) => {
  target.parentElement.parentElement.previousElementSibling.style.transform = 'translateX(-44vw)';
  // next[0].style.display = 'none';
  // previous[0].style.display = 'inline-block';
}

previous = (target) => {
  target.parentElement.parentElement.previousElementSibling.style.transform = 'translateX(0vw)';
  // previous[0].style.display = 'none';
  // next[0].style.display = 'inline-block';
}
* {
  font-family: "Segoe UI";
}

.shop {
  background-color: rgb(255, 255, 255);
  overflow: hidden;
  position: relative;
  margin: 10px;
  margin-top: 0;
}

.product-display-area {
  width: 81.5vw;
  display: inline-block;
}

.shop_header {
  margin: 10px;
  margin-bottom: 0px;
  position: relative;
  padding: 10px;
  border-bottom: 1px solid rgb(229, 229, 229);
  background-color: rgb(255, 255, 255);
}

.shop_header h2 {
  display: inline-block;
  font-weight: 500;
  margin-left: 30px;
}

.shop_header p {
  margin-left: 30px;
}

.shop_header .clock {
  display: inline-block;
  margin-left: 30px;
}

.shop_header .clock img {
  position: relative;
  top: 6px;
  width: 24px;
}

.shop_header .clock #time_remaining {
  margin-left: 10px;
}

.shop_header button[type="button"] a {
  text-decoration: none;
  padding: 10px 15px;
  display: inline-block;
  font-size: 15px;
  font-weight: 700;
  background-color: rgb(40, 116, 240);
  color: rgb(255, 255, 255);
}

.shop_header button[type="button"] {
  border: none;
  position: absolute;
  right: 20px;
  top: 0px;
}

.shop_items {
  width: 130vw;
  transition: 1s;
}

.shop_items .items {
  display: inline-block;
  padding: 25px;
}

.shop_items .items img {
  display: block;
  margin: auto;
}

.shop_items .items .item_info {
  text-align: center;
  margin: auto;
}

.shop_items .items .item_info p {
  padding: 5px;
  color: rgb(56, 142, 60);
  font-size: 14px;
}

.shop_items .items .item_info p:first-of-type {
  color: rgb(0, 0, 0);
  font-weight: 500;
}

.shop_items .items .item_info p:last-of-type {
  color: rgb(151, 151, 151);
}

.item_carousel_left_arrow {
  position: absolute;
  top: 35%;
  padding: 50px 20px;
  border-top-right-radius: 5px;
  border-bottom-right-radius: 5px;
  border: 1px solid rgb(209, 211, 213);
  background-color: rgb(255, 255, 255);
  cursor: pointer;
}

.item_carousel_right_arrow {
  right: 0;
  position: absolute;
  top: 35%;
  padding: 50px 20px;
  border-top-left-radius: 5px;
  border-bottom-left-radius: 5px;
  border: 1px solid rgb(209, 211, 213);
  background-color: rgb(255, 255, 255);
  cursor: pointer;
}
<link rel="stylesheet" href="https://kit-pro.fontawesome.com/releases/v5.15.1/css/pro.min.css">
<div class="product-display-area">
  <div class="shop" id="best_of_electronics">
    <div class="shop_header">
      <h2>Best of Electronics</h2>
      <p>Devices and Accessories</p>
      <button type="button"><a href="#">VIEW ALL</a></button>
    </div>
    <div class="shop_items">
      <a href="#">
        <div class="items">
          <div>
            <img src="https://rukminim1.flixcart.com/image/150/150/k4vmxzk0/cases-covers/back-cover/y/y/g/spigen-f23cs25961-original-imafnzhgzuty3gb6.jpeg?q=70">
          </div>
          <div class="item_info">
            <p class="product_name">Best Brands</p>
            <p class="product_price">Shop Now</p>
            <p class="product_company">For All Phone Models</p>
          </div>
        </div>
      </a>
      <a href="#">
        <div class="items">
          <div>
            <img src="https://rukminim1.flixcart.com/image/150/150/kdhphu80/sports-action-camera/j/f/k/4000-air-4k-full-hd-wifi-30m-waterproof-sports-action-camera-original-imafue3ghmhtk39f.jpeg?q=70">
          </div>
          <div class="item_info">
            <p class="product_name">Sports & Action Camera</p>
            <p class="product_price">From &#8377;4199</p>
            <p class="product_company">GoPro, SJCAM, DJI & more</p>
          </div>
        </div>
      </a>
      <a href="#">
        <div class="items">
          <div>
            <img src="https://rukminim1.flixcart.com/image/150/150/kbqu4cw0/speaker/soundbar/9/s/0/mt160dsb-motorola-original-imaftf6csukur9he.jpeg?q=70">
          </div>
          <div class="item_info">
            <p class="product_name">Dolby Enabled</p>
            <p class="product_price">Up to 50% Off</p>
            <p class="product_company">Home Theaters</p>
          </div>
        </div>
      </a>
      <a href="#">
        <div class="items">
          <div>
            <img src="https://rukminim1.flixcart.com/image/150/150/k6mibgw0/datacard/r/h/g/jiofi-jmr-541-original-imafpfhandhkptwc.jpeg?q=70">
          </div>
          <div class="item_info">
            <p class="product_name">Data Cards</p>
            <p class="product_price">Upto 60% off</p>
            <p class="product_company">JioFi, Huawei & more</p>
          </div>
        </div>
      </a>
      <a href="#">
        <div class="items">
          <div>
            <img src="https://rukminim1.flixcart.com/image/150/150/ja73ki80/webcam/pc-webcam/7/q/e/logitech-c310-original-imaeztzqny7jh7gh.jpeg?q=70">
          </div>
          <div class="item_info">
            <p class="product_name">Webcams</p>
            <p class="product_price">From &#8377;499</p>
            <p class="product_company">Logitech, Quantum & more</p>
          </div>
        </div>
      </a>
      <a href="#">
        <div class="items">
          <div>
            <img src="https://rukminim1.flixcart.com/image/150/150/kb5eikw0/trimmer/z/d/n/0-5-10-mm-bt3101-15-stainless-steel-cordless-philips-original-imafsjquyq2hapug.jpeg?q=70">
          </div>
          <div class="item_info">
            <p class="product_name">Trimmers & Hair Clippers</p>
            <p class="product_price">From &#8377;700</p>
            <p class="product_company">By Nova, Philips & more</p>
          </div>
        </div>
      </a>
      <a href="#">
        <div class="items">
          <div>
            <img src="https://rukminim1.flixcart.com/image/150/150/k51cpe80/hearing-aid/e/e/s/ha50-behind-ear-beurer-original-imafnth6bue82ngc.jpeg?q=70">
          </div>
          <div class="item_info">
            <p class="product_name">Best of Hearing Aids</p>
            <p class="product_price">From &#8377;499</p>
            <p class="product_company">Beurer & more</p>
          </div>
        </div>
      </a>
      <a href="#">
        <div class="items">
          <div>
            <img src="https://rukminim1.flixcart.com/image/150/150/kex5ci80/printer/k/n/z/hp-laserjet-pro-m1136-mfp-original-imafvhnbe2dg4vem.jpeg?q=70">
          </div>
          <div class="item_info">
            <p class="product_name">Top 10 Printers</p>
            <p class="product_price">&#8377;2399</p>
            <p class="product_company">Print, Scan & copy</p>
          </div>
        </div>
      </a>
    </div>
    <div>
      <span class="item_carousel_left_arrow" id="arruw" onclick="previous(event.target)">
                        <i class="fas fa-arrow-left"></i>
                    </span>
      <span class="item_carousel_right_arrow" id="arruw" onclick="next(event.target)">
                        <i class="fas fa-arrow-right"></i>
                    </span>
    </div>
  </div>
</div>

Answer

You need to delegate and test what you clicked since you have two elements you can click, the button and the <i>

Also you have duplicate IDs which is not allowed (had you used them)

Also DRY (don’t repeat yourself)

const shopItems = document.querySelector("#best_of_electronics .shop_items")

document.getElementById("nav").addEventListener("click", function(e) {
  let tgt = e.target;
  let possibleParent = tgt.closest("span")
  if (possibleParent) tgt = possibleParent; // we clicked the <i>
  shopItems.style.transform = tgt.id==="prev" ? 'translateX(-44vw)' : 'translateX(0vw)';
})
* {
  font-family: "Segoe UI";
}

.shop {
  background-color: rgb(255, 255, 255);
  overflow: hidden;
  position: relative;
  margin: 10px;
  margin-top: 0;
}

.product-display-area {
  width: 81.5vw;
  display: inline-block;
}

.shop_header {
  margin: 10px;
  margin-bottom: 0px;
  position: relative;
  padding: 10px;
  border-bottom: 1px solid rgb(229, 229, 229);
  background-color: rgb(255, 255, 255);
}

.shop_header h2 {
  display: inline-block;
  font-weight: 500;
  margin-left: 30px;
}

.shop_header p {
  margin-left: 30px;
}

.shop_header .clock {
  display: inline-block;
  margin-left: 30px;
}

.shop_header .clock img {
  position: relative;
  top: 6px;
  width: 24px;
}

.shop_header .clock #time_remaining {
  margin-left: 10px;
}

.shop_header button[type="button"] a {
  text-decoration: none;
  padding: 10px 15px;
  display: inline-block;
  font-size: 15px;
  font-weight: 700;
  background-color: rgb(40, 116, 240);
  color: rgb(255, 255, 255);
}

.shop_header button[type="button"] {
  border: none;
  position: absolute;
  right: 20px;
  top: 0px;
}

.shop_items {
  width: 130vw;
  transition: 1s;
}

.shop_items .items {
  display: inline-block;
  padding: 25px;
}

.shop_items .items img {
  display: block;
  margin: auto;
}

.shop_items .items .item_info {
  text-align: center;
  margin: auto;
}

.shop_items .items .item_info p {
  padding: 5px;
  color: rgb(56, 142, 60);
  font-size: 14px;
}

.shop_items .items .item_info p:first-of-type {
  color: rgb(0, 0, 0);
  font-weight: 500;
}

.shop_items .items .item_info p:last-of-type {
  color: rgb(151, 151, 151);
}

.item_carousel_left_arrow {
  position: absolute;
  top: 35%;
  padding: 50px 20px;
  border-top-right-radius: 5px;
  border-bottom-right-radius: 5px;
  border: 1px solid rgb(209, 211, 213);
  background-color: rgb(255, 255, 255);
  cursor: pointer;
}

.item_carousel_right_arrow {
  right: 0;
  position: absolute;
  top: 35%;
  padding: 50px 20px;
  border-top-left-radius: 5px;
  border-bottom-left-radius: 5px;
  border: 1px solid rgb(209, 211, 213);
  background-color: rgb(255, 255, 255);
  cursor: pointer;
}
<link rel="stylesheet" href="https://kit-pro.fontawesome.com/releases/v5.15.1/css/pro.min.css">
<div class="product-display-area">
  <div class="shop" id="best_of_electronics">
    <div class="shop_header">
      <h2>Best of Electronics</h2>
      <p>Devices and Accessories</p>
      <button type="button"><a href="#">VIEW ALL</a></button>
    </div>
    <div class="shop_items">
      <a href="#">
        <div class="items">
          <div>
            <img src="https://rukminim1.flixcart.com/image/150/150/k4vmxzk0/cases-covers/back-cover/y/y/g/spigen-f23cs25961-original-imafnzhgzuty3gb6.jpeg?q=70">
          </div>
          <div class="item_info">
            <p class="product_name">Best Brands</p>
            <p class="product_price">Shop Now</p>
            <p class="product_company">For All Phone Models</p>
          </div>
        </div>
      </a>
      <a href="#">
        <div class="items">
          <div>
            <img src="https://rukminim1.flixcart.com/image/150/150/kdhphu80/sports-action-camera/j/f/k/4000-air-4k-full-hd-wifi-30m-waterproof-sports-action-camera-original-imafue3ghmhtk39f.jpeg?q=70">
          </div>
          <div class="item_info">
            <p class="product_name">Sports & Action Camera</p>
            <p class="product_price">From &#8377;4199</p>
            <p class="product_company">GoPro, SJCAM, DJI & more</p>
          </div>
        </div>
      </a>
      <a href="#">
        <div class="items">
          <div>
            <img src="https://rukminim1.flixcart.com/image/150/150/kbqu4cw0/speaker/soundbar/9/s/0/mt160dsb-motorola-original-imaftf6csukur9he.jpeg?q=70">
          </div>
          <div class="item_info">
            <p class="product_name">Dolby Enabled</p>
            <p class="product_price">Up to 50% Off</p>
            <p class="product_company">Home Theaters</p>
          </div>
        </div>
      </a>
      <a href="#">
        <div class="items">
          <div>
            <img src="https://rukminim1.flixcart.com/image/150/150/k6mibgw0/datacard/r/h/g/jiofi-jmr-541-original-imafpfhandhkptwc.jpeg?q=70">
          </div>
          <div class="item_info">
            <p class="product_name">Data Cards</p>
            <p class="product_price">Upto 60% off</p>
            <p class="product_company">JioFi, Huawei & more</p>
          </div>
        </div>
      </a>
      <a href="#">
        <div class="items">
          <div>
            <img src="https://rukminim1.flixcart.com/image/150/150/ja73ki80/webcam/pc-webcam/7/q/e/logitech-c310-original-imaeztzqny7jh7gh.jpeg?q=70">
          </div>
          <div class="item_info">
            <p class="product_name">Webcams</p>
            <p class="product_price">From &#8377;499</p>
            <p class="product_company">Logitech, Quantum & more</p>
          </div>
        </div>
      </a>
      <a href="#">
        <div class="items">
          <div>
            <img src="https://rukminim1.flixcart.com/image/150/150/kb5eikw0/trimmer/z/d/n/0-5-10-mm-bt3101-15-stainless-steel-cordless-philips-original-imafsjquyq2hapug.jpeg?q=70">
          </div>
          <div class="item_info">
            <p class="product_name">Trimmers & Hair Clippers</p>
            <p class="product_price">From &#8377;700</p>
            <p class="product_company">By Nova, Philips & more</p>
          </div>
        </div>
      </a>
      <a href="#">
        <div class="items">
          <div>
            <img src="https://rukminim1.flixcart.com/image/150/150/k51cpe80/hearing-aid/e/e/s/ha50-behind-ear-beurer-original-imafnth6bue82ngc.jpeg?q=70">
          </div>
          <div class="item_info">
            <p class="product_name">Best of Hearing Aids</p>
            <p class="product_price">From &#8377;499</p>
            <p class="product_company">Beurer & more</p>
          </div>
        </div>
      </a>
      <a href="#">
        <div class="items">
          <div>
            <img src="https://rukminim1.flixcart.com/image/150/150/kex5ci80/printer/k/n/z/hp-laserjet-pro-m1136-mfp-original-imafvhnbe2dg4vem.jpeg?q=70">
          </div>
          <div class="item_info">
            <p class="product_name">Top 10 Printers</p>
            <p class="product_price">&#8377;2399</p>
            <p class="product_company">Print, Scan & copy</p>
          </div>
        </div>
      </a>
    </div>
    <div id="nav">
      <span class="item_carousel_left_arrow arrow" id="prev">
                        <i class="fas fa-arrow-left"></i>
                    </span>
      <span class="item_carousel_right_arrow arrow" id="next">
                        <i class="fas fa-arrow-right"></i>
                    </span>
    </div>
  </div>
</div>

If you must have inline handlers, you can pass (this) – it is the same as event.target and use the saved div

 <span class="item_carousel_left_arrow" id="prev" onclick="nav(this)">
   <i class="fas fa-arrow-left"></i>
 </span>
 <span class="item_carousel_right_arrow" id="next" onclick="nav(this)">
   <i class="fas fa-arrow-right"></i>
 </span>

using

 const shopItems = document.querySelector("#best_of_electronics .shop_items")
 function nav(span) {
   shopItems.style.transform = span.id==="prev" ? 'translateX(-44vw)' : 'translateX(0vw)';
 }


Source: stackoverflow