为什么轮播中的计数器达到0索引和max索引后返回负值?

时间:2018-12-04 21:24:43

标签: javascript jquery html carousel counter

为什么我的计数器达到0索引和max索引后会变为负值?我有代码应该在发生这种情况时将索引值重置为第一个或最后一个索引。当用户单击“下一个/上一个”,然后他们到达轮播的开头或结尾时,幻灯片的索引应根据当前索引位置重置为第一个或最后一个索引。

当用户单击下6次然后单击前3次时,我的幻灯片消失了。

如果有人可以帮助我,我将非常感谢!

$(function() {
    // Default controls
    var defControls = {
        content: "img", // accepts any DOM element - div, img, table, etc...
        showControls: true, // true/false shows/hides the carousel's navigational controls
        effect: "default", // supports default, fade, slide, verticalSlide, slidingFade
        effectDuration: 0.25, // to be used in conjunction with effect - adjust the time of the effect measured in seconds
        prevText: "« Previous", // previous button text
        nextText: "Next »", // next button text
        containerWidth: 600, // determines the width of the content container
        cycleback: false, // allows for cycling back through images
        autoplay: false, // automatically cycle through the slides in the carousel
        pauseTime: 10 // to be used in conjunction with autoplay - sets the pause time inbetween each slide
    };

    // Variable declarations
    var controls = {};

    // Checks for userControls
    if (typeof userControls !== "undefined") {
        controls = $.extend({}, defControls, userControls);
    } else {
        controls = defControls;
    }

    var contentType = $(controls.content);
    var $el = $("#showcase");
    var $leftArrow = "#left_arrow";
    var $rightArrow = "#right_arrow";
    var $load = $el.find(contentType)[0];
    var slideCount = $el.children().length;
    var slideContent = $el.children();
    var slideNum = 1;
    var counter = $(".active").index();

    // Checks if the content in the carousel is an img and then determines the width of the container based on the size of the content
    if (controls.content === "img") {
        controls.containerWidth = $(".slide").width();
    }

    // Preloads carousel with correct settings
    $el.css("width", controls.containerWidth);
    $el.find(contentType)[0].setAttribute("class", "active");

    // Checks to see if the setting for carousel controls are set to show on the page
    if (controls.showControls === true) {
        $(
            '<div id="controls"><a href="#" id="' +
                $leftArrow.replace("#", "") +
                '">' +
                controls.prevText +
                '</a> <a href="#" id="' +
                $rightArrow.replace("#", "") +
                '">' +
                controls.nextText +
                "</a></div>"
        ).insertAfter("#showcase");
        $("#controls").find("#left_arrow").addClass("disabled");
    }

    // Checks to see if the setting for cycleback is enabled
    if (controls.cycleback === true) {
        $("#controls").find("#left_arrow").removeClass("disabled");
    }

    // Checks to see if the setting for autoplay is enabled
    if (controls.autoplay === true) {
        $("#controls").find("#left_arrow").removeClass("disabled");
        controls.cycleback = true;
        var interval;
        var timer = function() {
            interval = setInterval(function() {
                $("#right_arrow").click();
            }, controls.pauseTime * 1000);
        };
        timer();
    }

    // Logic for the carousel effects
    function effects(action) {
        switch (controls.effect) {
            // Fade effect
            case "fade":
                if (controls.content == "img") {
                    $el.css("background", "#000");
                }

                $(".slide").stop().animate({ opacity: 0 }, controls.effectDuration * 300, function() {
                    $(".active").stop().animate({ opacity: 1 }, controls.effectDuration * 1000);
                });
                break;

            // Slide effect
            case "slide":
                if (action == "prev") {
                    $(".slide").css("left", -controls.containerWidth);
                    $(".slide")
                        .stop()
                        .animate({ left: -controls.containerWidth }, controls.effectDuration * 800,
                            function() {
                                $(".active").stop().animate({ left: 0 }, controls.effectDuration * 1000);
                            }
                        );
                } else if (action == "next") {
                    $(".slide").css("left", controls.containerWidth);
                    $(".slide")
                        .stop()
                        .animate({ left: controls.containerWidth }, controls.effectDuration * 800,
                            function() {
                                $(".active").stop().animate({ left: 0 }, controls.effectDuration * 1000);
                            }
                        );
                }
                break;

            case "verticalSlide":
                if (action == "prev") {
                    $(".slide").css("top", -controls.containerWidth);
                    $(".slide")
                        .stop()
                        .animate({ top: -controls.containerWidth }, controls.effectDuration * 800,
                            function() {
                                $(".active").stop().animate({ top: 0 }, controls.effectDuration * 1000);
                            }
                        );
                } else if (action == "next") {
                    $(".slide").css("top", controls.containerWidth);
                    $(".slide").stop().animate({ top: controls.containerWidth }, controls.effectDuration * 800,
                            function() {
                                $(".active").stop().animate({ top: 0 }, controls.effectDuration * 1000);
                            }
                        );
                }
                break;

            // Sliding fade effect
            case "slidingFade":
                if (action == "prev") {
                    $(".slide").css("left", -controls.containerWidth);
                    $(".slide").stop().animate({ left: -controls.containerWidth, opacity: 0 }, controls.effectDuration * 1400,
                            function() {
                                $(".active").stop().animate({ left: 0, opacity: 1 }, controls.effectDuration * 1200);
                            }
                        );
                } else if (action == "next") {
                    $(".slide").css("left", controls.containerWidth);
                    $(".slide").stop().animate({ left: controls.containerWidth, opacity: 0 }, controls.effectDuration * 1400,
                            function() {
                                $(".active").stop().animate({ left: 0, opacity: 1 }, controls.effectDuration * 1200);
                            });
                }
                break;

            // Default effect
            case "default":
                break;
        }
    }

    // Checks for the first and last index in the carousel
    function checkSlide() {
        if (controls.cycleback === false) {
            if (slideNum == 1) {
                $($leftArrow).addClass("disabled");
            } else {
                $($leftArrow).removeClass("disabled");
            }

            if (slideNum == slideCount) {
                $($rightArrow).addClass("disabled");
            } else {
                $($rightArrow).removeClass("disabled");
            }
        } else {
            $($leftArrow).removeClass("disabled");
            $($rightArrow).removeClass("disabled");
        }
    }

    // Navigational logic for the previous/next buttons
    $(document).on("click", $leftArrow, function(e) {
        if (controls.cycleback === false) {
            if (slideNum > 1) {
                counter--;
                $(".active").addClass("slide");
                $(".active").removeClass("active");
console.log(counter);
                // Sends the effect value to the switch
                effects("prev");
console.log(counter);
                $el.find(contentType).eq(counter).addClass("active");
                slideNum--;

                // Checks the current slide index
                checkSlide();
            }
            e.preventDefault();
        } else {
            if (slideNum > 1) {
                counter--;
                $(".active").addClass("slide");
                $(".active").removeClass("active");

                // Sends the effect value to the switch
                effects("prev");
console.log(counter);
                $el.find(contentType).eq(counter).addClass("active");
                slideNum--;

                // Checks the current slide index
                checkSlide();

                // Resets the autoplay timer if previous is clicked
                if (controls.autoplay === true) {
                    clearInterval(interval);
                    timer();
                }
            } else {
                counter = $(".active").index() + (slideNum - 1);
                $(".active").addClass("slide");
                $(".active").removeClass("active");

                // Sends the effect value to the switch
                effects("next");
console.log(counter);
                $el.find(contentType).eq(counter).addClass("active");
                slideNum++;

                // Checks the current slide index
                checkSlide();

                // Resets the autoplay timer if previous is clicked
                if (controls.autoplay === true) {
                    clearInterval(interval);
                    timer();
                }
            }
            e.preventDefault();
        }
    });

    $(document).on("click", $rightArrow, function(e) {
        if (controls.cycleback === false) {
            if (slideNum < slideCount) {
                counter++;
                $(".active").addClass("slide");
                $(".active").removeClass("active");
console.log(counter);
                // Sends the effect value to the switch
                effects("next");
console.log(counter);
                $el.find(contentType).eq(counter).addClass("active");
                slideNum++;

                // Checks the current slide index
                checkSlide();
            }
            e.preventDefault();
        } else {
            if (slideNum < slideCount) {
                counter++;
                $(".active").addClass("slide");
                $(".active").removeClass("active");

                // Sends the effect value to the switch
                effects("next");
console.log(counter);
                $el.find(contentType).eq(counter).addClass("active");
                slideNum++;

                // Checks the current slide index
                checkSlide();

                // Resets the autoplay timer if previous is clicked
                if (controls.autoplay === true) {
                    clearInterval(interval);
                    timer();
                }
            } else {
                counter = $(".active").index() - (slideCount - 1);
                $(".active").addClass("slide");
                $(".active").removeClass("active");

                // Sends the effect value to the switch
                effects("next");
console.log(counter);
                $el.find(contentType).eq(counter).addClass("active");
                slideNum++;

                // Checks the current slide index
                checkSlide();

                // Resets the autoplay timer if previous is clicked
                if (controls.autoplay === true) {
                    clearInterval(interval);
                    timer();
                }
            }
            e.preventDefault();
        }
    });
});
* {
	margin: 0px;
	padding: 0px;
}

#showcase {
	overflow: hidden;
	position: relative;
	background: green;
}

.disabled {
	color: red !important;
}

.slide {
	display: none;
	opacity: 0;
	position: relative;
}

.active {
	display: block;
	opacity: 1;
	position: relative;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="showcase">
	<img class="slide" src="https://picsum.photos/458/354/?image=306" />
	<img class="slide" src="https://picsum.photos/458/354/?image=626" />
	<img class="slide" src="https://picsum.photos/458/354/?image=806" />
	<!-- <div class="slide">content 1</div>
	<div class="slide">content 2</div>
	<div class="slide">content 3</div> -->
</div>

<script>
userControls = {
	effectDuration : .5,
	cycleback : true
}
</script>

1 个答案:

答案 0 :(得分:1)

计数器存在的问题是,它不能在任何给定方向上多次点击。

eq(n)是为什么您得到空白图片的问题。较大的索引(index > slideCount or index < -1 * slideCount)导致其超出范围。 eq(n)处理负数的唯一原因是因为它使用幻灯片数组的长度作为偏移量。

我已修复问题,以便当您达到0或slideCount并循环返回时,slideNum将会重置。

<script>
    $(function () {
        // Default controls
        var defControls = {
            content: "img", // accepts any DOM element - div, img, table, etc...
            showControls: true, // true/false shows/hides the carousel's navigational controls
            effect: "default", // supports default, fade, slide, verticalSlide, slidingFade
            effectDuration: 0.25, // to be used in conjunction with effect - adjust the time of the effect measured in seconds
            prevText: "&laquo; Previous", // previous button text
            nextText: "Next &raquo;", // next button text
            containerWidth: 600, // determines the width of the content container
            cycleback: false, // allows for cycling back through images
            autoplay: false, // automatically cycle through the slides in the carousel
            pauseTime: 10 // to be used in conjunction with autoplay - sets the pause time inbetween each slide
        };

        // Variable declarations
        var controls = {};

        // Checks for userControls
        if (typeof userControls !== "undefined") {
            controls = $.extend({}, defControls, userControls);
        } else {
            controls = defControls;
        }

        var contentType = $(controls.content);
        var $el = $("#showcase");
        var $leftArrow = "#left_arrow";
        var $rightArrow = "#right_arrow";
        var $load = $el.find(contentType)[0];
        var slideCount = $el.children().length;
        var slideContent = $el.children();
        var slideNum = 1;
        var counter = $(".active").index();

        // Checks if the content in the carousel is an img and then determines the width of the container based on the size of the content
        if (controls.content === "img") {
            controls.containerWidth = $(".slide").width();
        }

        // Preloads carousel with correct settings
        $el.css("width", controls.containerWidth);
        $el.find(contentType)[0].setAttribute("class", "active");

        // Checks to see if the setting for carousel controls are set to show on the page
        if (controls.showControls === true) {
            $(
                '<div id="controls"><a href="#" id="' +
                $leftArrow.replace("#", "") +
                '">' +
                controls.prevText +
                '</a> <a href="#" id="' +
                $rightArrow.replace("#", "") +
                '">' +
                controls.nextText +
                "</a></div>"
            ).insertAfter("#showcase");
            $("#controls").find("#left_arrow").addClass("disabled");
        }

        // Checks to see if the setting for cycleback is enabled
        if (controls.cycleback === true) {
            $("#controls").find("#left_arrow").removeClass("disabled");
        }

        // Checks to see if the setting for autoplay is enabled
        if (controls.autoplay === true) {
            $("#controls").find("#left_arrow").removeClass("disabled");
            controls.cycleback = true;
            var interval;
            var timer = function () {
                interval = setInterval(function () {
                    $("#right_arrow").click();
                }, controls.pauseTime * 1000);
            };
            timer();
        }

        // Logic for the carousel effects
        function effects(action) {
            switch (controls.effect) {
                // Fade effect
                case "fade":
                    if (controls.content == "img") {
                        $el.css("background", "#000");
                    }

                    $(".slide").stop().animate({
                        opacity: 0
                    }, controls.effectDuration * 300, function () {
                        $(".active").stop().animate({
                            opacity: 1
                        }, controls.effectDuration * 1000);
                    });
                    break;

                    // Slide effect
                case "slide":
                    if (action == "prev") {
                        $(".slide").css("left", -controls.containerWidth);
                        $(".slide")
                            .stop()
                            .animate({
                                    left: -controls.containerWidth
                                }, controls.effectDuration * 800,
                                function () {
                                    $(".active").stop().animate({
                                        left: 0
                                    }, controls.effectDuration * 1000);
                                }
                            );
                    } else if (action == "next") {
                        $(".slide").css("left", controls.containerWidth);
                        $(".slide")
                            .stop()
                            .animate({
                                    left: controls.containerWidth
                                }, controls.effectDuration * 800,
                                function () {
                                    $(".active").stop().animate({
                                        left: 0
                                    }, controls.effectDuration * 1000);
                                }
                            );
                    }
                    break;

                case "verticalSlide":
                    if (action == "prev") {
                        $(".slide").css("top", -controls.containerWidth);
                        $(".slide")
                            .stop()
                            .animate({
                                    top: -controls.containerWidth
                                }, controls.effectDuration * 800,
                                function () {
                                    $(".active").stop().animate({
                                        top: 0
                                    }, controls.effectDuration * 1000);
                                }
                            );
                    } else if (action == "next") {
                        $(".slide").css("top", controls.containerWidth);
                        $(".slide").stop().animate({
                                top: controls.containerWidth
                            }, controls.effectDuration * 800,
                            function () {
                                $(".active").stop().animate({
                                    top: 0
                                }, controls.effectDuration * 1000);
                            }
                        );
                    }
                    break;

                    // Sliding fade effect
                case "slidingFade":
                    if (action == "prev") {
                        $(".slide").css("left", -controls.containerWidth);
                        $(".slide").stop().animate({
                                left: -controls.containerWidth,
                                opacity: 0
                            }, controls.effectDuration * 1400,
                            function () {
                                $(".active").stop().animate({
                                    left: 0,
                                    opacity: 1
                                }, controls.effectDuration * 1200);
                            }
                        );
                    } else if (action == "next") {
                        $(".slide").css("left", controls.containerWidth);
                        $(".slide").stop().animate({
                                left: controls.containerWidth,
                                opacity: 0
                            }, controls.effectDuration * 1400,
                            function () {
                                $(".active").stop().animate({
                                    left: 0,
                                    opacity: 1
                                }, controls.effectDuration * 1200);
                            });
                    }
                    break;

                    // Default effect
                case "default":
                    break;
            }
        }

        // Checks for the first and last index in the carousel
        function checkSlide() {
            if (controls.cycleback === false) {
                if (slideNum == 1) {
                    $($leftArrow).addClass("disabled");
                } else {
                    $($leftArrow).removeClass("disabled");
                }

                if (slideNum == slideCount) {
                    $($rightArrow).addClass("disabled");
                } else {
                    $($rightArrow).removeClass("disabled");
                }
            } else {
                $($leftArrow).removeClass("disabled");
                $($rightArrow).removeClass("disabled");
            }
        }

        // Navigational logic for the previous/next buttons
        $(document).on("click", $leftArrow, function (e) {
            if (controls.cycleback === false) {
                if (slideNum > 1) {
                    $(".active").addClass("slide");
                    $(".active").removeClass("active");

                    slideNum--;
                    if (slideNum == -1) {
                        slideNum = slideCount;
                    }
                    counter = slideNum - 1;
                    console.log(counter);
                    // Sends the effect value to the switch
                    effects("prev");
                    console.log(counter);
                    $el.find(contentType).eq(counter).addClass("active");

                    // Checks the current slide index
                    checkSlide();
                }
                e.preventDefault();
            } else {

                slideNum--;
                if (slideNum == -1) {
                    slideNum = slideCount - 1;
                }
                counter = slideNum - 1;
                if (counter < 0) {
                    counter = counter + slideCount;
                }

                effects("prev");
                $(".active").addClass("slide");
                $(".active").removeClass("active");
                console.log(counter);
                $el.find(contentType).eq(counter).addClass("active");

                // Checks the current slide index
                checkSlide();

                // Resets the autoplay timer if previous is clicked
                if (controls.autoplay === true) {
                    clearInterval(interval);
                    timer();
                }

                e.preventDefault();
            }
        });

        $(document).on("click", $rightArrow, function (e) {
            if (controls.cycleback === false) {
                if (slideNum < slideCount) {
                    counter = slideNum;
                    $(".active").addClass("slide");
                    $(".active").removeClass("active");
                    console.log(counter);
                    // Sends the effect value to the switch
                    effects("next");
                    console.log(counter);
                    $el.find(contentType).eq(counter).addClass("active");

                    if (slideNum < slideCount) {
                        slideNum++;
                    }

                    // Checks the current slide index
                    checkSlide();
                }
                e.preventDefault();
            } else {
                if (slideNum < slideCount) {
                    counter = slideNum;
                    $(".active").addClass("slide");
                    $(".active").removeClass("active");

                    // Sends the effect value to the switch
                    effects("next");
                    console.log(counter);
                    $el.find(contentType).eq(counter).addClass("active");
                    slideNum++;

                    if (slideNum == slideCount) {
                        slideNum = 0;
                    } else if (slideNum < 0) {
                        slideNum = slideCount + slideNum;
                    }

                    // Checks the current slide index
                    checkSlide();

                    // Resets the autoplay timer if previous is clicked
                    if (controls.autoplay === true) {
                        clearInterval(interval);
                        timer();
                    }
                } else {
                    counter = (slideCount - slideNum);
                    $(".active").addClass("slide");
                    $(".active").removeClass("active");

                    // Sends the effect value to the switch
                    effects("next");
                    console.log(counter);
                    $el.find(contentType).eq(counter).addClass("active");
                    slideNum++;

                    if (slideNum == slideCount) {
                        slideNum = 0;
                    } else if (slideNum < 0) {
                        slideNum = slideCount + slideNum;
                    }

                    // Checks the current slide index
                    checkSlide();

                    // Resets the autoplay timer if previous is clicked
                    if (controls.autoplay === true) {
                        clearInterval(interval);
                        timer();
                    }
                }
                e.preventDefault();
            }
        });
    });
</script>