Search code examples
javascripthtmlcssdomcss-transforms

Cannot read property 'style' of undefined although everything works


I am making a carousel slider and, although it works as it should, i get this error: something.js:46 Uncaught TypeError: Cannot read property 'style' of undefined

The script that runs this code is set to run after the page has loaded using the following function

function ready(callback){
  // in case the document is already rendered
  if (document.readyState!='loading') callback();
  // modern browsers
  else if (document.addEventListener) document.addEventListener('DOMContentLoaded', callback);
  // IE <= 8
  else document.attachEvent('onreadystatechange', function(){
      if (document.readyState=='complete') callback();
  });
}

The carousel looks like this.

The structure of the HTML is this.

I have a script that generate the li objects with the necessary elements within.

var listElement = document.createElement("li");
var textElement = document.createElement("p");
var linkElement = document.createElement("a");
linkElement.setAttribute("href","/web/window/window.html");
var textContent = document.createTextNode(data.results[i].original_title);
textElement.appendChild(textContent);
listElement.setAttribute("class", "card");
listElement.setAttribute("data-target", "card")
var imgElement = document.createElement("IMG");
var imgPath = "https://image.tmdb.org/t/p/w780"+data.results[i].poster_path;
imgElement.setAttribute("src",imgPath)
linkElement.appendChild(imgElement);
listElement.appendChild(linkElement);
listElement.appendChild(textElement);
document.getElementById("ulMV").appendChild(listElement);

And finally the script that runs the carousel which is place in the head tag.

ready(function(){
  const carousel = document.querySelector("[data-target='carousel']");
  const card = carousel.getElementsByClassName("card");
  console.log(card)
  const leftButton = document.querySelector("[data-action='slideLeft']");
  const rightButton = document.querySelector("[data-action='slideRight']");


  let offset = 0;

  leftButton.addEventListener("click", function() {
    if (offset !== 0) {
      offset += 234;
      for(var x = 0;x<=card.length;x++){
        card[x].style.transform = `translateX(${offset}px)`;
      }
    }
  })

  rightButton.addEventListener("click", function() {
    offset -= 234;
    for(var x = 0;x<=card.length;x++){
      card[x].style.transform = `translateX(${offset}px)`;
    }

  })
})

This uses the ready function mentioned in the first place.

Everything works how it should but the error keeps appearing every time i press any of the two buttons.


Solution

  • for(var x = 0;x<=card.length;x++){
    

    Probably this line is a problem (of course every occurrence). Arrays are zero-indexed. length property returns just a number of items. If you think about amount of elements it may be from 1 to <number_of_elements>. But in loop context is from 0 to <number of elements> - 1.

    Let's say you have 4 elements.

    el1
    el2
    el3
    el4
    

    Number of els: 4 Your loop executes from 0 until card.length is higher or equal. So it executes for 0, 1, 2, 3 and 4. It executes 5 times, but you have only 4 elements. Change it just to x < card.length and it will work. Then if it hit i = 4 it will not execute because 4 < 4 is false.