2

The page works fine, but the slider doesn't slide to the next image. JSFiddle makes it work out fine and the images slide, yet on localhost or any live website it fails.

<script>

    var slides = document.querySelectorAll('#slides.klant');
var currentSlide = 0;
var slideInterval = setInterval(nextSlide,2000);

function nextSlide(){
    slides[currentSlide].className = 'klant';
    currentSlide = (currentSlide+1)%slides.length;
    slides[currentSlide].className = 'klant showing';
}


</script>

<title>Untitled Document</title>
</head>

<body>

<div id="ads">
<ul id="slides">
    <li class="klant showing"><img src="img/first.jpg"></li>
    <li class="klant"><img src="img/second.jpg"></li>
    <li class="klant"><img src="img/third.jpg"></li>
    <li class="klant"><img src="img/fourth.jpg"></li>
    <li class="klant"><img src="img/fifth.jpg"></li>
</ul>
</div>

I get an error "Uncaught TypeError: Cannot set property 'className' of undefined" on the slides[currentSlide].className = 'klant'; part of the function but can't figure out what's going wrong.

3
  • Please take a care look at timing. Your script in head is executed before body exists. Commented Sep 26, 2016 at 12:35
  • Place your <script> as last-child of <body>(Just before closing body tag(</body>)) Commented Sep 26, 2016 at 12:35
  • Move your script tag to the end of your document before the closing body tag. Commented Sep 26, 2016 at 12:38

3 Answers 3

1

With input from Teemu(see comments below), the major issue is that your script is loaded before the HTML. Thus, the elements are undefined at the point the script ran. Wrapping the script in an onload event should solve the problem and putting a space between #slides and .klant in your script. See below example:

<script>

window.onload = function () {
   var slides = document.querySelectorAll('#slides .klant');
   var currentSlide = 0;
   var slideInterval = setInterval(nextSlide,2000);


function nextSlide(){
        slides[currentSlide].className = 'klant';
        currentSlide = (currentSlide+1)%slides.length;
        slides[currentSlide].className = 'klant showing';
    }

 }

</script>
Sign up to request clarification or add additional context in comments.

6 Comments

This is magic, how would getElementsByClassName method find elements which are not even created yet?
They are created. See the HTML in the question
They are certainly not created, do you see </head><body> pair in the HTML? How is the script placed related to <body>? What is guaranteed to be executed before anything else in a HTML document? Where is slides defined? When it is referred?
@Teemu You also need to understand that there's a delay. This gives room for the HTML to be fully loaded and slides will definitely have values when nextSlide() is fired.
@Teemu Thanks for the input. I really understand now why it was magical :)
|
1

the script executes before the page finished loading, so the querySelectorAll returns an empty array. copy your script to the end of the <body> and it will work fine.

On JsFiddle it works because by default script executes there after load.

Comments

1
Just Replace
 line var slides = document.querySelectorAll('#slides.klant');

with

    var sliderparent = document.getElementById('slides');
var slides = sliderparent.querySelectorAll('.klant');

1 Comment

yes, right have to replace whole script tag in bottom of page, Thank @Teemu

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.