1
\$\begingroup\$

I have a slideshow in jQuery slideshow switching picture automatically every 5 seconds with CSS3 transitions. The current picture has the current class, the previous picture has the forrige class and the next picture has the neste class. The first picture on page load has the first class to avoid animation, and a baklengs class when the user goes backwards by keyboard or pagination (needs different styling as seen below). This is to style the classes in CSS like this:

#slideshow article:not(.first) { transition: left 1s; }
#slideshow article.current { left: 0; z-index: 3; }
#slideshow article.forrige { left: -100%; }
#slideshow article.neste { left: 100%; }
#slideshow article.neste:not(.baklengs), #slideshow article.forrige.baklengs { z-index: 1; }
#slideshow article.forrige:not(.baklengs), #slideshow article.neste.baklengs { z-index: 2; }

This is working fine, but as it is coded by me in 60 lines, it may be some things that could have been better. I'm specifically hinting to how the previous and next classes are added. There are currently always 3 slides, it should be that way and is coded that way, but if I at one point should add more, or less, slides, it should work.

if(jQuery("#slideshow article:nth-of-type(2)").hasClass("current")) {
    jQuery("#slideshow article:first-of-type").addClass("forrige");
    jQuery("#slideshow article:nth-of-type(3)").addClass("neste");
}
else if(jQuery("#slideshow article:first-of-type").hasClass("current")) {
    jQuery("#slideshow article:last-of-type").addClass("forrige");
    jQuery("#slideshow article:nth-of-type(2)").addClass("neste");
}
else if(jQuery("#slideshow article:last-of-type").hasClass("current")) {
    jQuery("#slideshow article:nth-of-type(2)").addClass("forrige");
    jQuery("#slideshow article:first-of-type").addClass("neste");
}

As you can see, when on the third slide, the first slide should get the next class, and when on the first slide, the last slide should get the previous class.

This isn't a semantic way of doing it, I know, but it works for now.

Here's the full code:

var stopp, baklengs, antall = jQuery("#slideshow article").length, index = 0;
function slideTo(idx) {
    jQuery("#slideshow article, #slideshow nav a").removeAttr("class").filter(':nth-of-type(' + (idx+1) + ')').addClass("current");
    if(jQuery("#slideshow article:nth-of-type(2)").hasClass("current")) {
        jQuery("#slideshow article:first-of-type").addClass("forrige");
        jQuery("#slideshow article:nth-of-type(3)").addClass("neste");
    }
    else if(jQuery("#slideshow article:first-of-type").hasClass("current")) {
        jQuery("#slideshow article:last-of-type").addClass("forrige");
        jQuery("#slideshow article:nth-of-type(2)").addClass("neste");
    }
    else if(jQuery("#slideshow article:last-of-type").hasClass("current")) {
        jQuery("#slideshow article:nth-of-type(2)").addClass("forrige");
        jQuery("#slideshow article:first-of-type").addClass("neste");
    }
    if(index > idx && !(index == antall - 1 && idx == 0) || (index == 0 && idx == antall - 1)) {
        jQuery("#slideshow article:not(.current)").addClass("baklengs");
    }
    index = idx;
};
function startCycle() {
    stopp = setInterval(function() {
        jQuery("#slideshow article").stop(true, true);
        var idx = index + 1 > antall - 1 ? 0 : index + 1;
        slideTo(idx);
    }, 5500);
}; 
if (antall > 1) {
    jQuery("#slideshow").append("<nav>");
    jQuery("#slideshow article").each(function() {
        jQuery("#slideshow nav").append("<a>&bull;</a>");
    }).filter(":first-of-type").addClass("current first");
    jQuery("#slideshow article:nth-of-type(2)").addClass("neste");
    jQuery("#slideshow article:last-of-type").addClass("forrige");
    startCycle();
    jQuery("#slideshow nav a").click(function() {
        clearInterval(stopp);
        startCycle();
        var idx = jQuery("#slideshow nav a").index(this);
        if (index === idx) return;
        slideTo(idx);
    }).filter(":first-of-type").addClass("current");
    jQuery(document).keyup(function(e) {
        if (e.keyCode == 37) {
            clearInterval(stopp);
            startCycle();
            var idx = index - 1 < 0 ? antall - 1 : index - 1;
            slideTo(idx);
        } 
        else if (e.keyCode == 39) {
            clearInterval(stopp);
            startCycle();
            var idx = index + 1 > antall - 1 ? 0 : index + 1;
            slideTo(idx);
        }
    });
}
\$\endgroup\$
0
\$\begingroup\$

I got it working after a while by forcing me to use the logical part of my brain. So this:

if(jQuery("#slideshow article:nth-of-type(2)").hasClass("current")) {
    jQuery("#slideshow article:first-of-type").addClass("forrige");
    jQuery("#slideshow article:nth-of-type(3)").addClass("neste");
}
else if(jQuery("#slideshow article:first-of-type").hasClass("current")) {
    jQuery("#slideshow article:last-of-type").addClass("forrige");
    jQuery("#slideshow article:nth-of-type(2)").addClass("neste");
}
else if(jQuery("#slideshow article:last-of-type").hasClass("current")) {
    jQuery("#slideshow article:nth-of-type(2)").addClass("forrige");
    jQuery("#slideshow article:first-of-type").addClass("neste");
}

Became this simple code:

jQuery("#slideshow article:nth-of-type(" + (idx > 0 ? idx : antall) + ")").addClass("forrige");
jQuery("#slideshow article:nth-of-type(" + (idx < antall - 1 ? idx + 2 : 1) + ")").addClass("neste");

Now when I add more slides, everything continues to work.

Thanks for not helping me, haha. However, if you have other suggestions to improve the code, please let me know (and I will upvote your answer, of course).

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.