多个 jQuery 幻灯片不会保持同步
Multiple jQuery slideshows won't stay in sync
我正在使用一个简单的 jQuery 脚本来 运行 一个 fade-in/out 幻灯片。 (我是 jQ 的 nubee。)我正在 运行ning 幻灯片放映的 3 个实例来控制 3 个单独的幻灯片区域。幻灯片使用淡入、延迟和淡出计时。以下是每个脚本的控制代码行:
slides.eq(slideCount).fadeIn(1000).delay(6000).fadeOut(1000, function(){
slides.eq(slideCount).fadeIn(2250).delay(3500).fadeOut(2250, function(){
slides.eq(slideCount).fadeIn(3000).delay(2000).fadeOut(3000, function(){
想法是每张幻灯片的总屏幕时间为 8 秒。开始时很好,但如果我让它 运行 一段时间,3 张幻灯片就会不同步。这破坏了页面的布局。我可以看到,我的假设是将淡入、延迟和淡出时间加在一起,但有一个小增量是有缺陷的。有谁知道是否有调整来纠正这个问题?
您可以在此处查看当前的幻灯片:Slideshow。如果您观看显示屏几分钟就没事了,可能需要大约 15 分钟才能开始不同步。一种解决方案是让页面在 x 次迭代后刷新。有没有办法将其添加到脚本中?任何想法将不胜感激。
完整脚本如下:
$(function() {
var slides = $('.slideShowA>li');
var slideCount = 0;
var totalSlides = slides.length;
var slideCache = [];
(function preloader() {
if (slideCount < totalSlides) {
// Load Images
slideCache[slideCount] = new Image();
slideCache[slideCount].src = slides.eq(slideCount).find('img').attr('src');
slideCache[slideCount].onload = function() {
slideCount++;
preloader();
}
} else {
// Run the slideshow
slideCount = 0;
SlideShow();
}
}());
function SlideShow() {
// Your code goes here
slides.eq(slideCount).fadeIn(1000).delay(6000).fadeOut(1000, function() {
slideCount < totalSlides - 1 ? slideCount++ : slideCount = 0;
SlideShow();
});
}
});
您需要将三个单独的幻灯片视为一次显示三个图像的幻灯片。这应该不难,因为三个列表的图片数量相同。
我不确定这是否重要,但您也可以尝试异步预加载图像。也就是说,您可以一次加载所有图像,而不是等待每个图像都加载完再加载下一个图像。您可以使用 JQuery 的 Deferred
对象在它们全部加载后执行代码。
假设您的 HTML 看起来像这样:
<div id="media-col">
<div>
<ul>
<li><img ... /></li>
<li><img ... /></li>
<li><img ... /></li>
<li><img ... /></li>
</ul>
</div>
<div>
<ul>
<li><img ... /></li>
<li><img ... /></li>
<li><img ... /></li>
<li><img ... /></li>
</ul>
</div>
<div>
<ul>
<li><img ... /></li>
<li><img ... /></li>
<li><img ... /></li>
<li><img ... /></li>
</ul>
</div>
</div>
你有以下 CSS:
#media-col li {
opacity: 0;
display: none;
}
您的代码可能如下所示:
$(function() {
var TIMES = [
{ preDelay: 0, fadeIn: 3000, delay: 2000, fadeOut: 3000 },
{ preDelay: 1500, fadeIn: 500, delay: 4000, fadeOut: 500 },
{ preDelay: 1000, fadeIn: 1000, delay: 4000, fadeOut: 1000 }
];
var $container = $('#media-col');
// This function preloads an image and returns a Deferred object that is resolved
// when the image's onload function is called.
function preloadImage(url) {
return $.Deferred(function(deferred) {
var image = new Image();
image.src = url;
image.onload = function() {
image.onload = null;
deferred.resolve(image);
}
});
}
// Asynchronously preload all the images for the slideshows.
var preloads = $container.find('img').map(function() {
return preloadImage($(this).attr('src'));
}).get();
// This will start the slideshow when all the images have been preloaded.
$.when.apply($, preloads).done(function() {
var $lists = $container.find('ul'),
slideCount = $lists.first().children().length;
(function showSlide(slideIndex) {
var $items = $lists.children(':nth-child(' + slideCount + 'n - ' + (slideCount - 1 - slideIndex) + ')');
var promises = $items.show().map(function(i) {
var t = TIMES[i];
return $(this).delay(t.preDelay).fadeTo(t.fadeIn, 1).delay(t.delay).fadeTo(t.fadeOut, 0).promise();
});
$.when.apply($, promises).done(function() {
$items.hide();
showSlide((slideIndex + 1) % slideCount);
});
})(0);
});
});
为了同步动画,上面的代码使用 $.when()
和 .promise()
returns 一个承诺,当 JQuery 对象上的动画是完成..
上面的代码没有使用 .fadeOut()
,而是使用了 .fadeTo()
。然后 .hide()
可以在所有动画完成后调用。这样,所有项目都会同时隐藏。这也允许 "pre" 延迟。如果您不想要,可以轻松将其删除。
我正在使用一个简单的 jQuery 脚本来 运行 一个 fade-in/out 幻灯片。 (我是 jQ 的 nubee。)我正在 运行ning 幻灯片放映的 3 个实例来控制 3 个单独的幻灯片区域。幻灯片使用淡入、延迟和淡出计时。以下是每个脚本的控制代码行:
slides.eq(slideCount).fadeIn(1000).delay(6000).fadeOut(1000, function(){
slides.eq(slideCount).fadeIn(2250).delay(3500).fadeOut(2250, function(){
slides.eq(slideCount).fadeIn(3000).delay(2000).fadeOut(3000, function(){
想法是每张幻灯片的总屏幕时间为 8 秒。开始时很好,但如果我让它 运行 一段时间,3 张幻灯片就会不同步。这破坏了页面的布局。我可以看到,我的假设是将淡入、延迟和淡出时间加在一起,但有一个小增量是有缺陷的。有谁知道是否有调整来纠正这个问题?
您可以在此处查看当前的幻灯片:Slideshow。如果您观看显示屏几分钟就没事了,可能需要大约 15 分钟才能开始不同步。一种解决方案是让页面在 x 次迭代后刷新。有没有办法将其添加到脚本中?任何想法将不胜感激。
完整脚本如下:
$(function() {
var slides = $('.slideShowA>li');
var slideCount = 0;
var totalSlides = slides.length;
var slideCache = [];
(function preloader() {
if (slideCount < totalSlides) {
// Load Images
slideCache[slideCount] = new Image();
slideCache[slideCount].src = slides.eq(slideCount).find('img').attr('src');
slideCache[slideCount].onload = function() {
slideCount++;
preloader();
}
} else {
// Run the slideshow
slideCount = 0;
SlideShow();
}
}());
function SlideShow() {
// Your code goes here
slides.eq(slideCount).fadeIn(1000).delay(6000).fadeOut(1000, function() {
slideCount < totalSlides - 1 ? slideCount++ : slideCount = 0;
SlideShow();
});
}
});
您需要将三个单独的幻灯片视为一次显示三个图像的幻灯片。这应该不难,因为三个列表的图片数量相同。
我不确定这是否重要,但您也可以尝试异步预加载图像。也就是说,您可以一次加载所有图像,而不是等待每个图像都加载完再加载下一个图像。您可以使用 JQuery 的 Deferred
对象在它们全部加载后执行代码。
假设您的 HTML 看起来像这样:
<div id="media-col">
<div>
<ul>
<li><img ... /></li>
<li><img ... /></li>
<li><img ... /></li>
<li><img ... /></li>
</ul>
</div>
<div>
<ul>
<li><img ... /></li>
<li><img ... /></li>
<li><img ... /></li>
<li><img ... /></li>
</ul>
</div>
<div>
<ul>
<li><img ... /></li>
<li><img ... /></li>
<li><img ... /></li>
<li><img ... /></li>
</ul>
</div>
</div>
你有以下 CSS:
#media-col li {
opacity: 0;
display: none;
}
您的代码可能如下所示:
$(function() {
var TIMES = [
{ preDelay: 0, fadeIn: 3000, delay: 2000, fadeOut: 3000 },
{ preDelay: 1500, fadeIn: 500, delay: 4000, fadeOut: 500 },
{ preDelay: 1000, fadeIn: 1000, delay: 4000, fadeOut: 1000 }
];
var $container = $('#media-col');
// This function preloads an image and returns a Deferred object that is resolved
// when the image's onload function is called.
function preloadImage(url) {
return $.Deferred(function(deferred) {
var image = new Image();
image.src = url;
image.onload = function() {
image.onload = null;
deferred.resolve(image);
}
});
}
// Asynchronously preload all the images for the slideshows.
var preloads = $container.find('img').map(function() {
return preloadImage($(this).attr('src'));
}).get();
// This will start the slideshow when all the images have been preloaded.
$.when.apply($, preloads).done(function() {
var $lists = $container.find('ul'),
slideCount = $lists.first().children().length;
(function showSlide(slideIndex) {
var $items = $lists.children(':nth-child(' + slideCount + 'n - ' + (slideCount - 1 - slideIndex) + ')');
var promises = $items.show().map(function(i) {
var t = TIMES[i];
return $(this).delay(t.preDelay).fadeTo(t.fadeIn, 1).delay(t.delay).fadeTo(t.fadeOut, 0).promise();
});
$.when.apply($, promises).done(function() {
$items.hide();
showSlide((slideIndex + 1) % slideCount);
});
})(0);
});
});
为了同步动画,上面的代码使用 $.when()
和 .promise()
returns 一个承诺,当 JQuery 对象上的动画是完成..
上面的代码没有使用 .fadeOut()
,而是使用了 .fadeTo()
。然后 .hide()
可以在所有动画完成后调用。这样,所有项目都会同时隐藏。这也允许 "pre" 延迟。如果您不想要,可以轻松将其删除。