相关文章推荐
Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Learn more about Collectives

Teams

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Learn more about Teams

I'm currently working on a website where I use Strapi as a CMS and Next.js(React) in Frontend. The site also has an image slider which obviousely contains an image, a headline and a description.

After some time on the website the following error occurs and the slider stops from working or does things like showing all slides really fast one behind the other. What can I do to solve this?

Unhandled Runtime Error TypeError: Canot read property 'classList' of undefined

I've already tried many solutions I found here on StackOverflow, but nothing worked... I am just not able to find the error in my code, which is the following: (/components/image-slider file)

    import ...
const Slider = ({...}) => {
 if (typeof window !== 'undefined') {
    var slides = document.querySelectorAll('.slide');
    var btns = document.querySelectorAll('.btn-navig');
    let currentSlide = 1;
    // Javascript for image slider manual navigation
    var manualNav = function(manual){
        slides.forEach((slide) => {
        slide.classList.remove('active');
        btns.forEach((btn) => {
            btn.classList.remove('active');
        slides[manual].classList.add('active');
        btns[manual].classList.add('active');
        btns.forEach((btn, i) => {
        btn.addEventListener("click", () => {
            manualNav(i);
            currentSlide = i;
        // // Javascript for image slider autoplay navigation
        var repeat = function(activeClass){
        let active = document.getElementsByClassName('active');
        let i = 1;
        var repeater = () => {
            setTimeout(function(){
            [...active].forEach((activeSlide) => {
                activeSlide.classList.remove('active');
            slides[i].classList.add('active');
            btns[i].classList.add('active');
            if(slides.length == i){
            i = 0;
            if(i >= slides.length){
            return;
            repeater();
        }, 10000);
        repeater();
        repeat();
    if (error) {
        return <div>An error occured: {error.message}</div>;
    return (
        <div className="img-slider">
            <div className="slide active">
                <div className="info">
                   // content 
            <div className="slide">
                <div className="info">
                // content 
            // further slides
            <div className="navigation">
                <div className="btn-navig active"></div>
                <div className="btn-navig"></div>
                <div className="btn-navig"></div>
// axios request ...
export default Slider;

I hope someone can help me with the above mentioned problem. Thanks a lot!

You need to move all the if block to useEffect because the first time this code run slides and btn, etc are null/undefined – lissettdm Apr 22, 2021 at 19:35

Your first flaw in the code is this one

var manualNav = function(manual){
    slides.forEach((slide) => {
    slide.classList.remove('active');
    btns.forEach((btn) => {
        btn.classList.remove('active');
    slides[manual].classList.add('active');
    btns[manual].classList.add('active');

Here, with every new slide of slides[], you start a new btns[] loop.

    btns.forEach((btn) => {
        btn.classList.remove('active');

But this is just unnecessary processing time that gets lost. Do it this way:

var manualNav = function(manual){
    slides.forEach((slide) => {
        slide.classList.remove('active');
    btns.forEach((btn) => {
        btn.classList.remove('active');
    slides[manual].classList.add('active');
    btns[manual].classList.add('active');

Your actual problem is this.

You have 3 div with the class btn-navig but only 2 with the class slide. But in your repeater() you increase i by 1 with every new loop.

 slides[i].classList.add('active');
 btns[i].classList.add('active');

With the second iteration you have the following situation:

 slides[2].classList.add('active');  // undefined
 btns[2].classList.add('active'); // value

There is no slides[2] as only slides[0] and slides[1] have values.

You have to rethink your indexing-approach.

Ok, wow - thanks a lot for your help! I think it could work when adding the following code after the if statements: if(i >= slides.lenght > 2) { window.clearInterval(); return; } – malu15 Apr 23, 2021 at 7:11

Thanks for contributing an answer to Stack Overflow!

  • Please be sure to answer the question. Provide details and share your research!

But avoid

  • Asking for help, clarification, or responding to other answers.
  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.

 
推荐文章