0

在过去的几天里,我一直在为产品页面制作图像滑块,并且我已经设法构建了一个我觉得足够令人满意的滑块,但是我想要添加到它的最后润色不是静态运动从一个图像到下一个图像,您会看到一个物理滑动动画,我遇到的唯一问题是它允许多次单击,这意味着这些值被完全抛出并且它只是中断。我想知道如何检查函数何时运行,以便在完成之前无法再次运行它,或者我想也许我可以使用 .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;
}
4

1 回答 1

1

只需检查您在单击 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单击的元素的属性处。

于 2013-06-18T11:08:11.970 回答