0

I am trying to implement this answer: https://stackoverflow.com/a/30581545/10471818 into my code however I get the error: Uncaught TypeError: Cannot read property 'classList' of undefined, this is my code:

What should I do instead? it shows the error on this line: $items[nextItem].classList.add('show'); I think it does update live to not target the figures properly

let slide = {};
async function updateProduct(colorElement) {
    await resetBorder();
    await hideSlideshow();
    document.querySelector(`.${colorElement}`).classList.add('border-enabled');
    document.querySelector(`.${colorElement}-slideshow`).style.display = 'block';
    slide.current = `.${colorElement}-slideshow`;
}

(function () {
    let counter = 0,
        $items = querySelectorAllLive(document, `${slide.current} figure`),
        itemsAmount = $items.length;
        console.log($items);

    const showItem = function () {
        const nextItem = Math.abs(counter % itemsAmount);

        [].forEach.call($items, function (el) {
            el.classList.remove('show');
        });

        $items[nextItem].classList.add('show');
    };

    document.querySelector('.next').addEventListener('click', function () {
        counter++;
        showItem();
        updateOrder();
    }, false);

    document.querySelector('.prev').addEventListener('click', function () {
        counter--;
        showItem();
        updateOrder();
    }, false);
})();

function querySelectorAllLive(element, selector) {
    var result = Array.prototype.slice.call(element.querySelectorAll(selector));

    var observer = new MutationObserver(function (mutations) {
        mutations.forEach(function (mutation) {
            [].forEach.call(mutation.addedNodes, function (node) {
                if (node.nodeType === Node.ELEMENT_NODE && node.matches(selector)) {
                    result.push(node);
                }
            });
        });
    });

    observer.observe(element, {
        childList: true,
        subtree: true
    });

    return result;
}
.slideshow {
  position: relative;
  display: block;
  overflow: hidden;
}

figure {
  position: absolute;
  opacity: 0;
  transition: 1s opacity;
}

figure.show {
  opacity: 1;
  position: static;
  transition: 1s opacity;
}

.prev {
  position: absolute;
  left: 7%;
  top: 50%;
  transform: translate(-50%, -50%);
  -webkit-transform: rotate(90deg);
  -ms-transform: rotate(90deg);
  transform: rotate(90deg);
}

.next {
  position: absolute;
  right: 7%;
  top: 50%;
  transform: translate(-50%, -50%);
  -webkit-transform: rotate(-90deg);
  -ms-transform: rotate(-90deg);
  transform: rotate(-90deg);
}

.box {
  height: 50px;
  width: 50px;
  -webkit-box-shadow: 0 0 7px black;
  box-shadow: 0 0 7px black;
}

.platin {
  background: rgb(255, 255, 255);
  background: linear-gradient(220deg,
    rgba(255, 255, 255, 1) 0%,
    rgba(110, 110, 110, 1) 100%);
}
<div class="slideshow platin-slideshow">
            <figure class="show" data-product="950 PLATIN - €7500"><img id="mi-image" src="assets/img/svg/950 PLATIN.svg"
                    height="280"></figure>
            <figure data-product="950 PLATIN - BLUE SAPPHIRE - €7500"><img id="mi-image" src="assets/img/svg/950 PLATIN - BLUE SAPPHIRE.svg"
                    height="280"></figure>
            <figure data-product="950 PLATIN - GREEN SAPPHIRE - €7500"><img id="mi-image" src="assets/img/svg/950 PLATIN - GREEN SAPPHIRE.svg"
                    height="280"></figure>
            <figure data-product="950 PLATIN - YELLOW SAPPHIRE - €7500"><img id="mi-image" src="assets/img/svg/950 PLATIN - YELLOW SAPPHIRE.svg"
                    height="280"></figure>
        </div>
<span class="prev"><img src="assets/img/svg/arrow.svg" height="80"></span>
<span class="next"><img src="assets/img/svg/arrow.svg" height="80"></span>

<div class="box platin" onClick="updateProduct('platin')"></div>

2 Answers2

0

You declare

let slide = {};

and then the self-invoking function is executed

(function () {
    let counter = 0,
        $items = querySelectorAllLive(document, `${slide.current} figure`),
        itemsAmount = $items.length;
        console.log($items);
        ...
 }

at the time slide is just a empy object where you try access slide.current which is undefined

correct me if i'm wrong

NoLogig
  • 131
  • 7
  • Yes, that is why I tried to implement the live querySelectorAllLive function to check for changes live or does it not work like this? –  Nov 13 '18 at 09:02
  • `slide` is just an empy object at the time the Template-String resolve it. the first time slide.current exist is after the line slide.current = `.${colorElement}-slideshow`; – NoLogig Nov 13 '18 at 09:10
0

I fixed the problem:

let slide = {
    current: '.silver-slideshow'
};
async function updateProduct(colorElement) {
    await resetBorder();
    await hideSlideshow();
    document.querySelector(`.${colorElement}`).classList.add('border-enabled');
    document.querySelector(`.${colorElement}-slideshow`).style.display = 'block';
    slide.current = `.${colorElement}-slideshow`;
}

let counter = 0;
const showItem = function (items) {
    let $items = document.querySelectorAll(`${items} figure`),
        itemsAmount = $items.length;

    const nextItem = Math.abs(counter % itemsAmount);

    [].forEach.call($items, function (el) {
        el.classList.remove('show');
    });

    $items[nextItem].classList.add('show');
};

document.querySelector('.next').addEventListener('click', function () {
    counter++;
    showItem(slide.current);
    updateOrder();
}, false);

document.querySelector('.prev').addEventListener('click', function () {
    counter--;
    showItem(slide.current);
    updateOrder();
}, false);