创建动画图像滑块 - 如何对多次单击进行动画处理和限制



在过去的几天里,我一直在为产品页面制作图像滑块,并且我已经设法构建了我认为足够令人满意的滑块,但是我想添加到它的最后润色不是从一个图像到下一个图像的静态移动,你会看到一个物理滑动动画, 我遇到的唯一问题是它允许多次点击,这意味着值被完全抛弃并且它只是中断。我想知道如何检查函数何时运行,以便在完成之前无法再次运行它,或者我想也许我可以使用 .finish(( 这样用户就不会被迫等待动画在每次单击之前完成,这样如果他们想快速滚动它会将之前的动画冲向最终值。

这是(当前(工作滑块的jsfiddle链接。

如果您在第 12 行和第 24 行将 .css(( 更改为 .animate((,您将看到我在箭头上多次单击时遇到的问题。

.HTML

<div id="imageSlider">
    <div id="imagesContainer">
        <div class="left imagePane" id="selectedImage">
            <div class="sliderImageAlign">
                <p style="height: 100px; width: 75px; line-height: 100px; text-align: center;">1</p>
            </div>
        </div>
        <div class="left imagePane">
            <div class="sliderImageAlign">
                <p style="height: 100px; width: 75px; line-height: 100px; text-align: center;">2</p>
            </div>
        </div>
        <div class="left imagePane">
            <div class="sliderImageAlign">
                <p style="height: 100px; width: 75px; line-height: 100px; text-align: center;">3</p>
            </div>
        </div>
        <div class="left imagePane">
            <div class="sliderImageAlign">
                <p style="height: 100px; width: 75px; line-height: 100px; text-align: center;">4</p>
            </div>
        </div>
        <div class="left imagePane">
            <div class="sliderImageAlign">
                <p style="height: 100px; width: 75px; line-height: 100px; text-align: center;">5</p>
            </div>
        </div>
    </div>
    <div id="imagesUp">
        <div id="imagesArrowUp"></div>
    </div>
    <div id="imagesDown">
        <div id="imagesArrowDown"></div>
    </div>
</div>

jQuery

$(document).ready(function () {
    var imageHeight = $("#selectedImage").height(),
        containerHeight = $("#imagesContainer").height(),
        imageSliderHeight = $("#imageSlider").height() - ($("#imagesDown")[0].offsetHeight + $("#imagesUp")[0].offsetHeight);
    $("#imagesDown").on('click', function () {
        if (containerHeight > imageSliderHeight) {
            var containerPos = $("#imagesContainer").position().top,
                containerNewPos = containerPos - imageHeight;
            if (imageSliderHeight < (containerHeight + containerPos)) {
                $("#imagesContainer").css({
                    top: containerNewPos + 'px'
                }, 800);
            }
        }
    });
    $("#imagesUp").on('click', function () {
        var containerPos = $("#imagesContainer").position().top,
            containerNewPos = containerPos + imageHeight;
        if (containerNewPos < imageHeight) {
            $("#imagesContainer").css({
                top: containerNewPos + 'px'
            }, 800);
        }
    });
});

.CSS

* {
    color: RGB(0, 0, 0);
    font: 14px Arial;
    margin: 0;
    padding: 0;
    text-decoration: none;
}
.left {
    float: left;
}
.right {
    float: right;
}
#imageSlider {
    border: 1px solid RGB(0, 0, 0);
    box-shadow: 0px 0px 10px RGB(200, 200, 200);
    float: left;
    height: 450px;
    margin-right: 20px;
    overflow: hidden;
    position: relative;
    width: 87px;
}
#imagesContainer {
    position: absolute;
    top: 35px;
    width: 100%;
}
#imagesUp,
#imagesDown {
    background: RGB(20, 100, 150);
    box-sizing: border-box;
        -moz-box-sizing: border-box;
        -webkit-box-sizing: border-box;
    height: 35px;
    position: absolute;
    width: 100%;
}
#imagesUp {
    border-bottom: 1px solid RGB(0, 0, 0);
    top: 0;
}
#imagesDown {
    border-top: 1px solid RGB(0, 0, 0);
    bottom: 0;
}
#imagesArrowUp,
#imagesArrowDown {
    border-left: 20px solid transparent;
    border-right: 20px solid transparent;
    margin: 0 auto;
    margin-top: 10px;
    height: 0;
    width: 0;
}
#imagesArrowUp {
    border-bottom: 15px solid RGB(200, 230, 240);
}
#imagesArrowDown {
    border-top: 15px solid RGB(200, 230, 240);
}
#selectedImage {
    background: RGBA(20, 100, 150, 0.4);
}
.sliderImageAlign {
    border: 1px solid RGB(0, 0, 0);
    height: 100px;
    margin: 5px;
    width: 75px;
}

只需检查您在使用 jQuery :animated伪类单击时元素是否仍在移动,例如以这种方式

$("#imagesUp").on('click', function () {
     var ic = $("#imagesContainer");
     ...
     if (ic.is(':not(:animated)') && containerNewPos < imageHeight) {
        ic.animate({
                top: containerNewPos + 'px'
        }, 800);
     }
});

这样做只有在前一个动画已完成时才能进行动画。

您还可以在处理程序中将该条件作为第一个语句进行检查,并根据自己的方便情况在该语句中移动所有必要的逻辑。

作为旁注,我建议重构您的代码,缓存对移动元素的引用并使用单个事件处理程序,用于 imageUp 和 imageDown 元素,因此您可以计算新的顶部属性(和运行动画的条件(只查看单击的元素的 id 属性。

最新更新