创建动画图像滑块 - 如何设置动画并限制多次点击?

时间:2013-06-18 10:34:23

标签: jquery html css

过去几天我花了一个产品页面的图像滑块,我已经设法构建了我认为足够令人满意的滑块,但是我要添加的最后一点是比从一个图像到下一个图像的静态移动,你看到一个物理滑动动画,我唯一的问题是它允许多次点击,这意味着值被完全抛出,它只是打破。我想知道如何检查函数何时运行,以便在完成之前无法再次运行它,或者我想也许我可以使用.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;
}

1 个答案:

答案 0 :(得分: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属性。

相关问题