jQuery幻灯片当我添加按钮时中断

时间:2015-07-13 14:40:33

标签: javascript jquery html css slideshow

我一直在尝试创建一个幻灯片,可以通过无线电(或几乎任何类型)按钮进行更改。我已经让幻灯片本身工作了,可以看到here,然而,当我尝试在等式中添加按钮时,整个事情就会中断。现在所有它都显示我是最后的图片,然后它逐渐消失到倒数第二张图片。这是我目前正在使用的功能。

    $(function () {
    "use strict";
    setInterval(function(){rotateImages()}, 4000);

    var pic1 = $('#slideshow div:first');
    var pic2 = $('#slideshow div:nth-child(2)');
    var pic3 = $('#slideshow div:nth-child(3)');
    var pic4 = $('#slideshow div:nth-child(4)');
    var pic5 = $('#slideshow div:last');

    $("#choosePic1").click(rotateImages(pic1));
    $("#choosePic2").click(rotateImages(pic2));
    $("#choosePic3").click(rotateImages(pic3));
    $("#choosePic4").click(rotateImages(pic4));
    $("#choosePic5").click(rotateImages(pic5)); 

});

function rotateImages(manualChange) {


    var CurrentPhoto = $('#slideshow .current');
   if (manualChange !== null) {
        CurrentPhoto = manualChange;   
    }
    var NextPhoto = CurrentPhoto.next();
    if (NextPhoto.length === 0) {
        NextPhoto = $('#slideshow div:first');
    }
    CurrentPhoto.removeClass('current').addClass('previous');
    NextPhoto.css({
        opacity: 0.0
    }).addClass('current')
        .animate({
        opacity: 1.0
    }, 1000,

    function () {
        CurrentPhoto.removeClass('previous');
    });
}

我已经在JSFiddle上留下了CSS和HTML伴奏,可以看到here

为什么当我添加按钮时整个功能会中断?

2 个答案:

答案 0 :(得分:2)

我认为您的想法是根据点击显示相应的图片。你正在做的是,将手动选择设置为当前图像,而你应该将它设置为下一个图像,因为它将根据你的逻辑显示。

您还可以将setInterval替换为setTimeout,以确保在下一个队列开始之前动画始终完成。

要检查是否将参数传递给函数,您可以简单地执行if (param)而不是if (param !== null)

您还必须通过.length检查元素是否存在,即使在您的情况下没有必要,因为您在图像和按钮之间有正确的映射。

最重要的部分是:

用户体验:每当您需要根据设置的间隔中断自动播放的动画时,请清除间隔。如果你不这样做,这将是一个糟糕的经历,因为即使人们不想要它,自动播放也会继续,因为手动干预的整个点就是看到那个特定的图像!

代码优化:Jquery / JavaScript提供了通过各种内置方法最小化代码的方法。利用它们可以减少您编写的代码行,并使将来更容易管理。我做了click位作为演示。我相信在这个片段中还有更多内容。

看看下面的修改后的代码。

$(function () {
    "use strict";
    var timer = setInterval(rotateImages, 2000);
    
    $(".buttons").on("click", ".slideshowSelect", function() {
        
        clearInterval(timer);
        var photoIndex = parseInt($(this).val(), 10) - 1;
        rotateImages( $('#slideshow div').eq(photoIndex) );
        
        //Give an option to the user thru a button to resume auto play
        //or resume auto play after a set amount of time
        setTimeout(function() {
            timer = setInterval(rotateImages, 2000);
        }, 5000);
    });
    
    function rotateImages(manualChange) {

        var CurrentPhoto = $('#slideshow .current');
        var NextPhoto = CurrentPhoto.next();
        
        if (manualChange && manualChange.length) {
            NextPhoto = manualChange;
        }
        if (NextPhoto.length === 0) {
            NextPhoto = $('#slideshow div:first');
        }
        CurrentPhoto.removeClass('current').addClass('previous');
        NextPhoto.css({
            opacity: 0.0
        }).addClass('current')
        .animate({
            opacity: 1.0
        }, 1000, function () {
            CurrentPhoto.removeClass('previous');
        });
    }
});
#slideshow div {
    z-index: 0;
    position: absolute;
}
#slideshow div.previous {
    z-index: 1;
}
#slideshow div.current {
    z-index: 2;
}
.slideshowSelect {
   height:22px;
    width: 22px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="slideshow">

    <span class="buttons">
        <input type="button" class="slideshowSelect" value="1" />
        <input type="button" class="slideshowSelect" value="2" />
        <input type="button" class="slideshowSelect"value="3" />
        <input type="button" class="slideshowSelect" value="4" />
        <input type="button" class="slideshowSelect" value="5" />
    </span>

    <div class="current">
        <img src="http://www.butterfly-tattoo-design.com/butterfly-tattoos-6926.jpg" alt="Img" width="300" />
    </div>
    <div>
        <img src="http://www.serendipitystamps.com/mm5/pics/stamps/1255FloralButterflyStamp.gif" alt="Img" width="300" />
    </div>
    <div>
        <img src="http://images.clipartpanda.com/free-butterfly-clipart-RcGjaR7cL.jpeg" alt="Img" width="300" />
    </div>
    <div>
        <img src="http://www.cgvector.com/wp-content/uploads/2011/04/Vector_Butterfly_000018.jpg" alt="Img" width="300" />
    </div>
    <div>
        <img src="http://www.weddingchaos.co.uk/images-content/animals/butterfly.jpg" alt="Img" width="300" />
    </div>
</div>

答案 1 :(得分:1)

  1. 由于您的$("#choosePic1").click(rotateImages(pic1));将使用pic1立即调用旋转的图片,因此您必须使用.bindclick事件创建新函数打电话给param。

  2. if (manualChange !== null)只有在manualChange更改为空时,如果您没有为manualChange提供价值并离开undefined,则为真test将变为false,然后CurrentPhoto将分配undefined

  3. 在您的逻辑中,CurrentPhoto = manualChange;中应分配的内容应为NextPhoto = manualChange;,因为您的意图似乎会更改用户选择的图片。

  4. 添加.stop(true, true)以使动画直接跳到应该播放的最后一个。

  5. :nth-child(2)将与#sildeshow中的第2个孩子匹配,但在#slideshow中,第一个元素是<span>,因此$('#slideshow div:first')将选择与$('#slideshow div:nth-of-type(2)')相同的项目,以及其他人。您应该使用:nth-of-type(2)选择#slideshow中的第二个div,以及其他人。

  6. 您可以进一步使用setTimeout而不是setInterval,然后更容易取消下一次自动旋转,防止它与手动播放动画重叠,并在rotateImages结束时设置setTimeout以使其重新启动自动播放

  7. &#13;
    &#13;
    $(function () {
        "use strict";
        setInterval(function () {
            rotateImages()
        }, 4000);
    
        var pic1 = $('#slideshow div:first');
        var pic2 = $('#slideshow div:nth-of-type(2)');
        var pic3 = $('#slideshow div:nth-of-type(3)');
        var pic4 = $('#slideshow div:nth-of-type(4)');
        var pic5 = $('#slideshow div:last');
        
        // use .bind to create new function which when executed, will execute rotateImages and pass picX as its param.
        $("#choosePic1").click(rotateImages.bind(null, pic1));
        $("#choosePic2").click(rotateImages.bind(null, pic2));
        $("#choosePic3").click(rotateImages.bind(null, pic3));
        $("#choosePic4").click(rotateImages.bind(null, pic4));
        $("#choosePic5").click(rotateImages.bind(null, pic5));
    
    });
    
    function rotateImages(manualChange) {
     
    
        var CurrentPhoto = $('#slideshow .current');
        var NextPhoto;
        // Use != null to test undefined and null
        if (manualChange != null) {
            // Assign it to NextPhoto
            NextPhoto = manualChange;
        } else {
            NextPhoto = CurrentPhoto.next();
        }
        if (NextPhoto.length === 0) {
            NextPhoto = $('#slideshow div:first');
        }
        CurrentPhoto.removeClass('current').addClass('previous');
        // Use .stop to skip current playing (if caused by autoRotate) and start the newest.
        NextPhoto.stop(true, true).css({
            opacity: 0.0
        }).addClass('current')
            .animate({
            opacity: 1.0
        }, 1000,
    
        function () {
            CurrentPhoto.removeClass('previous');
        });
    }
    &#13;
    #slideshow div {
        z-index: 0;
        position: absolute;
    }
    #slideshow div.previous {
        z-index: 1;
    }
    #slideshow div.current {
        z-index: 2;
    }
    .slideshowSelect {
       height:22px;
        width: 22px;
    }
    &#13;
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
    <div id="slideshow"> <span class="buttons">
                     <input type="button" id="choosePic1" class="slideshowSelect" value="1">
                    <input type="button" id="choosePic2" class="slideshowSelect" value="2">
                    <input type="button" id="choosePic3" class="slideshowSelect"value="3" >
                    <input type="button" id="choosePic4" class="slideshowSelect" value="4">
                    <input type="button" id="choosePic5" class="slideshowSelect" value="5">
                    </span> 
        <div class="current">
            <img src="http://lorempixel.com/400/200/abstract/" alt="Img" height="382" width="594">
        </div>
        <div>
            <img src="http://lorempixel.com/400/200/people/" alt="Img" height="382" width="594">
        </div>
        <div>
            <img src="http://lorempixel.com/400/200/sports/" alt="Img" height="382" width="594">
        </div>
        <div>
            <img src="http://lorempixel.com/400/200/animals/" alt="Img" height="382" width="594">
        </div>
        <div>
            <img src="http://lorempixel.com/400/200/nature/" alt="Img" height="382" width="594">
        </div>
    </div>
    &#13;
    &#13;
    &#13;