我一直在尝试创建一个可以用单选按钮(或者实际上,任何类型的按钮)更改的幻灯片。我已经让幻灯片本身工作了,可以在这里看到,然而,当我试图添加按钮到方程式,整个东西坏了。现在它给我看的都是最后一张图片,然后它会淡出到倒数第二张图片。这是我目前使用的函数。
$(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>
-
因为你的
$("#choosePic1").click(rotateImages(pic1));
会立即使用pic1
调用旋转的图像,你必须使用.bind
为click
事件创建一个新的函数来调用给定参数 -
if (manualChange !== null)
将仅在manualChange
更改为null时为真,如果您不给manualChange
赋值并留下undefined
,则if测试将变为假,然后CurrentPhoto将分配undefined
。 -
在你的逻辑中,你应该在
CurrentPhoto = manualChange;
中分配的应该是NextPhoto = manualChange;
,因为你的意图似乎改变了用户选择的图片。 -
添加一个
.stop(true, true)
,使动画直接跳转到最后一个应该播放的动画 -
:nth-child(2)
将匹配#sildeshow
中的第2个子元素,然而,在您的#slideshow
中,第一个元素是<span>
,因此$('#slideshow div:first')
将选择与$('#slideshow div:nth-of-type(2)')
相同的项目,从而选择其他项目。你应该使用:nth-of-type(2)
来选择#slideshow
中的第二个div,所以对其他人来说。 -
你可以进一步使用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>