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



我一直在尝试创建一个可以用单选按钮(或者实际上,任何类型的按钮)更改的幻灯片。我已经让幻灯片本身工作了,可以在这里看到,然而,当我试图添加按钮到方程式,整个东西坏了。现在它给我看的都是最后一张图片,然后它会淡出到倒数第二张图片。这是我目前使用的函数。

    $(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');
    });
}

我把CSS和HTML的附件留在了JSFiddle上,可以在这里看到。

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

我想你的想法是显示相应的图像来基于点击。你所做的是,将手动选择设置为当前图像,而你应该将其设置为下一个图像,因为这是将按照逻辑显示的内容。

你也可以将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. 因为你的$("#choosePic1").click(rotateImages(pic1));会立即使用pic1调用旋转的图像,你必须使用.bindclick事件创建一个新的函数来调用给定参数

  2. if (manualChange !== null)将仅在manualChange更改为null时为真,如果您不给manualChange赋值并留下undefined,则if测试将变为假,然后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来重新启动自动播放。

$(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');
    });
}
#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/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>

最新更新