@mUchenik

Почему не работает споллер?

Друзья, всем привет!
Колдовал над споллером (аккордион).
Перепроверить на 100раз, всё должно работать, но не тут то было.
В консоли возникает ошибка:
Uncaught TypeError: Cannot read properties of undefined (reading 'split')

Ни как не могу понять, что нужно, что б поправить проблемку.
Ниже указываю код и прикрепляю ссылку на кодепен:
<body>
    <div data-spollers data-one-spoller class="block block__1">
        <div class="block__item">
            <button tabindex="-1" type="button" data-spoller class="block__title">Обычный споллер 1</button>
            <div class="block__text">Далеко-далеко за словесными горами в стране гласных и согласных живут рыбные тексты.</div>
        </div>
        <div class="block__item">
            <button tabindex="-1" type="button" data-spoller class="block__title">Обычный споллер 2</button>
            <div class="block__text">2 Далеко-далеко за словесными горами в стране гласных и согласных живут рыбные тексты.</div>
        </div>
        <div class="block__item">
            <button tabindex="-1" type="button" data-spoller class="block__title">Обычный споллер 3</button>
            <div class="block__text">3 Далеко-далеко за словесными горами в стране гласных и согласных живут рыбные тексты.</div>
        </div>
    </div>

    <div data-spollers="650, min" class="block__2">
        <div class="block__item">
            <button tabindex="-1" type="button" data-spoller class="block__title">Споллера работает на экранах 650</button>
            <div class="block__text">3 Далеко-далеко за словесными горами в стране гласных и согласных живут рыбные тексты.</div>
        </div>
    </div>

    <div data-spollers="800, max" class="block__3">
        <div class="block__item">
            <button tabindex="-1" type="button" data-spoller class="block__title">Споллера работает на экранах 800</button>
            <div class="block__text">3 Далеко-далеко за словесными горами в стране гласных и согласных живут рыбные тексты.</div>
        </div>
        <div class="block__item">
            <button tabindex="-1" type="button" data-spoller class="block__title">Споллера работает на экранах 800</button>
            <div class="block__text">3 Далеко-далеко за словесными горами в стране гласных и согласных живут рыбные тексты.</div>
        </div>
        
    </div>
    <script src="js/spoler.js"></script>
</body>


CSS:
.wrapper {
    min-height: 100%;
    padding: 50px;
}

.block {
    margin: 0px 0px 30px 0px;
}

.block__item {
    margin: 0px 0px 10px 0px;
}
.block__title {
    width: 10%;
    text-align: left;
    font-size: 18px;
    border-color: transparent;
    color: #fff;
    padding: 10px;
    position: relative;
}
.block .__init .block__title {
    cursor: pointer;
}
.block .__init .block__title {
    padding: 10px 40px 10px 10px;
}

.block .__init .block__title::before,
.block .__init .block__title::after {
    content: "";
    width: 20px;
    height: 1px;
    background-color: #fff;
    position: absolute;
    right: 10px;
    top: 20px;
    transition: transform 0.3s ease 0s;
}

.block .__init .block__title::after {
    transform: rotate(-90deg);
}
.block .__init .block__title.__active::after {
    transform: rotate(0deg);
}
.block__text {
    padding: 0 10px 10px;
    line-height: 130%;
}

.block__1 .block__item {
    background-color: #77608d;
}

.block__2 .block__item {
    background-color: #794f45;
}
.block__3 .block__item {
    background-color: #7a956b;
}


js:
// spollers
const spollersArray = document.querySelectorAll('[data-spollers]');
if (spollersArray.length > 0) {
    //Получение обычных споллеров
    const spollersRegular = Array.from(spollersArray).filter(function (item, index, self) {
        return !item.dataset.sppollers.split(",")[0];
    });
    // Инициализация обычных споллеров
    if (spollersRegular.length > 0) {
        initSpollers(spollersRegular);
    }

    // Получение спойлеров с медиа запросами
    const spollersMedia = Array.from(spollersArray).filter(function (item, index, self){
        return item.dataset.sppollers.split(",")[0];
    });

    //Инициализация спойлеров
    if (spollersMedia.length > 0) {
        const breakpointsArray = [];
        spollersMedia.forEach(item => {
            const params = item.dataset.sppollers;
            const breakpoint = {};
            const paramsArray = params.split(",");
            breakpoint.value = paramsArray[0];
            breakpoint.type = paramsArray[1] ? paramsArray[1].trim() : "max";
            breakpoint.item = item;
            breakpointsArray.push(breakpoint);
        });

        //Получаем уникальные брейкпоинты
        let mediaQueries = breakpointsArray.map(function(item) {
            return '(' + item.type + "-width: " + item.value + "px)," + item.value + ',' + item.type;
        });
        mediaQueries = mediaQueries.filter(function (item, index, self) {
            return self.indexOf(item) === index;
        });

        //Работа с каждым брейпоинтом
        mediaQueries.forEach(breakpoint => {
            const paramsArray = breakpoint.split(",");
            const mediaBreakpoint = paramsArray[1];
            const mediaType = paramsArray[2];
            const matchMedia = window.matchMedia(paramsArray[0]);

            //Объекты с нужными условиями
            const spollersArray = breakpointsArray.filter(function(item) {
                if (item.value === mediaBreakpoint &&  item.type === mediaType) {
                    return true;
                }
            });
            //Событие
            matchMedia.addEventListener(function() {
                initSpollers(spollersArray, matchMedia);
            });
            initSpollers(spollersArray, matchMedia);
        });

    }

    //Инициализация
    function initSpollers(spollersArray, matchMedia = false) {
        spollersArray.forEach(spollersBlock => {
            spollersBlock = matchMedia ?  spollersBlock.item : spollersBlock;
            if (matchMedia.matches || !matchMedia) {
                spollersBlock.claccList.add('__init');
                initSpollerBody(spollersBlock);
                spollersBlock.addEventListener("click", setSpollerAction);
            }
            else {
                spollersBlock.claccList.remove('__init');
                initSpollerBody(spollersBlock, false);
                spollersBlock.addEventListener("click", setSpollerAction)
            }
        });
    }
    //Работа с контентом
    function initSpollerBody(spollersBlock, hideSpollerBody = true) {
        const spollerTitles = spollersBlock.querySelectorAll('[data-spoller]');
        if (spollerTitles.length > 0) {
            spollerTitles.forEach(spollerTitle => {
                if (hideSpollerBody) {
                    spollerTitle.removeAttribute('tabindex');
                    if(!spollerTitle.claccList.contains('__active')) {
                        spollerTitle.nextElementSibling.hidden = true;
                    }
                }
                else {
                    spollerTitle.setAttribute('tabindex', '-1');
                    spollerTitle.nextElementSibling.hidden = false;
                }
            });
        }
    }

    function setSpollerAction(e) {
        const el = e.target;
        if (el.hasAttribute('data-spoller') ||el.closet('[data-spoller]')) {
            const spollerTitle = el.hasAttribute('data-spoller') ? el : el.closet('[data-spoller]');
            const spollersBlock = spollerTitle.closet('[data-spollers]');
            const oneSpoller = spollersBlock.hasAttribute('data-one-spoller') ? true : false;
            if (!spollersBlock.querySelectorAll('.__slide').length) {
                if (oneSpoller && !spollerTitle.claccList.contains('__active')) {
                    hideSpollerBody(spollersBlock);
                }
                spollerTitle.claccList.toggle('__active');
                _slideToggle(spollerTitle.nextElementSibling, 500);
            }
            e.prentDefault();
        }
    }
    function hideSpollerBody(spollersBlock) {
        const spollerActiveTitle = spollersBlock.querySelector('[data-spoller].__active');
        if (spollerActiveTitle) {
            spollerActiveTitle.claccList.remove('__active');
            _slideUp(spollerActiveTitle.nextElementSibling, 500);
        }
    }
}

ссылка на кодепен
  • Вопрос задан
  • 115 просмотров
Пригласить эксперта
Ответы на вопрос 1
Starina_js
@Starina_js
full-stack web dev
Потому что у вас ошибка на ошибке)

- не claccList, а classList,
- не sppollers / sppoller, а spollers / spoller
и тут
matchMedia.addEventListener(function () {
        initSpollers(spollersArray, matchMedia);
      });


Какое событие должно отслеживаться для matchMedia ? click?

matchMedia.addEventListener('click', function() {
                initSpollers(spollersArray, matchMedia);
            });


Сначала смотрите в консоль, она рассказывает где ошибки.
Но даже исправив такие , то все равно надо разобраться как это все должно работать)
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы