简体   繁体   English

带有JQuery的滑块动画句柄,使用promise的悬停元素问题

[英]Slider animation handle with JQuery, hover element issue using promises

I have problem with a slider. 我有一个滑块问题。 It works correctly without one, strange for me, situation. 它可以正常工作,而不会出现我感到奇怪的情况。 When I mouseover fast from one dot to another, it will not wait until previous animation ends and two texts overlap. 当我将鼠标从一个点快速移到另一个点时,它不会等到上一个动画结束并且两个文本重叠时再显示。 Can somebody older and wiser help me? 年龄更大,更聪明的人可以帮助我吗?

HTML structure of project: 项目的HTML结构:

<section class="product-section">
<div class="vertical-text vertical-text-custom-5">
    Pluginy
</div>
<div class="carrousel-image-container-1 product-release-management">
    <i class="image-carrousel-1"></i>
</div>
<div class="carrousel-image-container-2 product-SLA">
    <i class="image-carrousel-2"></i>
</div>
<div class="carrousel-image-container-3 product-test-management">
    <i class="image-carrousel-3"></i>
</div>
<div class="col-custom-5">
    <div class="col-custom-7 text-size-xl">
        <div class="text-container-17">
            <div class="product product-release-management">
                <span class="text-color-6 text-weight-thin">Rivet</span> <br>
                <span class="text-color-5 text-weight-bold">Release Management</span> <br>
                <span class="text-color-3 text-weight-bold">plugin</span>
            </div>
            <div class="product product-SLA">
                <span class="text-color-6 text-weight-thin">Rivet</span> <br>
                <span class="text-color-5 text-weight-bold">SLA</span> <br>
                <span class="text-color-3 text-weight-bold">plugin</span>
            </div>
            <div class="product product-test-management">
                <span class="text-color-6 text-weight-thin">Rivet</span> <br>
                <span class="text-color-5 text-weight-bold">Test Management</span> <br>
                <span class="text-color-3 text-weight-bold">plugin</span>
            </div>
        </div>
        <div id="carrousel-dots-contener" class="carrousel-dots text-color-5">
            <div class="dot-container" data-carrousel-dot='dot-1'>
                <div class="dot-border">
                    <div class="dot dot-custom-2">&#9679;</div>
                </div>
            </div>
            <!--
                 -->
            <div class="dot-container" data-carrousel-dot='dot-2'>
                <div class="dot-border">
                    <div class="dot dot-custom-2">&#9679;</div>
                </div>
            </div>
            <!--
                 -->
            <div class="dot-container" data-carrousel-dot='dot-3'>
                <div class="dot-border">
                    <div class="dot dot-custom-2">&#9679;</div>
                </div>
            </div>
        </div>
    </div>
</div>

REST OF CODE HERE 其余代码在这里

These are the main issues: 这些是主要问题:

  • The promise() call works fine when you are sure you don't need to interrupt the animation, but as soon as you have mouse events that need immediate action (like hideAll ), this promise will become a problem: it will still resolve, but at an inconvenient moment. 当您确定不需要中断动画时, promise()调用可以很好地工作,但是一旦您的鼠标事件需要立即采取行动(例如hideAll ),这个promise就会成为问题:它仍然可以解决,但在不便的时刻。 In fact, as soon as you do another animation like hideAll , you want to cancel the execution of the code that follows the resolved promise. 实际上,一旦您执行另一个诸如hideAll的动画,您就想取消执行已解决的promise之后的代码。 So... add a condition before proceeding with fadeIn() to see that the product selection is still relevant. 所以...在继续进行fadeIn()之前添加一个条件,以查看产品选择仍然相关。

  • runInterval calls cyclicChange immediately, which is great when the page loads, but which is a bit annoying when moving the mouse over one dot to the next: as the mouse may exit the area, runInterval gets called and makes the selection jump to potentially another dot, which makes it kinda jumpy. runInterval立即调用CycleChange ,这在页面加载时非常好,但是在将鼠标移到一个点到下一个点时有点烦人:由于鼠标可能退出该区域, 因此会调用runInterval并使选择跳到另一个点,这让它有点跳动。 It is better to remove this immediate call to cyclicChange and then to add some code to show the first product when start runs. 最好删除对CycleChange的立即调用,然后添加一些代码以在启动运行时显示第一个产品。

  • To avoid unwanted queuing of animations, you could call stop(true) before doing fadeOut() . 为了避免不必要的动画排队,可以在执行fadeOut()之前调用stop(true) fadeOut()

I applied these changes to your JavaScript code, where I also made some other improvements, unrelated to the problem: 我将这些更改应用于您的JavaScript代码,并在其中进行了其他一些与问题无关的改进:

var carrousel = (function() {

    var interval = null,
        products,
        current = -1;

    products = [
        '.product-release-management',
        '.product-SLA',
        '.product-test-management'
    ];

    function showProduct(id) {
        // Avoid unnecessary work
        if (id == current) return; // nothing to do;
        // In other cases: hide first
        hideAll();
        current = id;
        $('.product').promise().done(function() {
            // Make sure selection is still like at the start of showProduct execution
            if (current === id) $(products[current]).fadeIn(500);
        });
        $("div[data-carrousel-dot='dot-" + (current + 1) + "']").addClass('dot-active');
    }        
    function hideAll() {
        // 1. easier selector for selecting all product classes
        // 2. stop any ongoing animation
        $(products.join(",")).stop(true, true).fadeOut(500); 
        $("div[data-carrousel-dot").removeClass('dot-active');
    }
    function cyclicChange() {
        if ( isNaN(interval) ) return; // timer is not active
        showProduct((current + 1) % products.length); // easier way to roundtrip
    }
    function runInterval(){
        interval = setInterval(cyclicChange, 3000); 
    }
    function mouseOverDotHandler() {
        $('.dot-container').hover(    
            function() {
                // Easier way to get number
                showProduct($(this).index());
            }
        );

        $('#carrousel-dots-contener').hover(
            function(){
                clearInterval(interval);
                interval = null; // use variable for indicating the pause
            },
            runInterval
        );
    }

    return {
        start: function() {
            showProduct(0);
            runInterval();
            mouseOverDotHandler();
        }
    }
})();

$(document).ready(function(){
    carrousel.start();
});

See it run on jsbin.com . 看到它在jsbin.com上运行。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM