我想知道使用JavaScript / jQuery为网站构建Infinity-Image-Loop-Slider的最佳(良好可读代码,害虫练习代码,可重用性)概念是什么?我不知道如何编写幻灯片的代码,但是什么蓝图符合上面提到的要求。 我的问题的主要焦点是如何安排图片以获得无限循环滑块的印象。
通过查看不同Sliders的Code,我遇到了两个解决方案:
- 每次显示下一张/上一张图像时,更改所有图像的z-Index。
- 改变图像在DOM中的位置。
但是检查和理解他人的代码非常耗时 - 这就是我问这个问题的原因: - )
答案 0 :(得分:58)
tl; dr - 示例:http://jsbin.com/ufoceq/8/
创建无限图像滑块而不需要太多努力的简单方法如下:为简单起见,假设您有<n>
个图像在循环中滑动,以便在{{1}之后} th 图像下一个可视化的是n
st (反之亦然)。
这个想法是创建第一个和最后一个图像的克隆,以便
无论你的图像数量是多少,你最多只需要添加2个克隆元素。
再次为简单起见,假设所有图像都是1
宽并且它们被包裹在一个容器中,您可以使用100px
左/右移动到剪切的蒙版中。然后,所有图片都可以轻松排成一行,并在容器上设置overflow: hidden
和display: inline-block
(现在更容易使用white-space: nowrap
。)
对于flexbox
DOM结构将是这样的:
n = 4
一开始,您的容器将定位offset(px) 0 100 200 300 400 500
images | 4c | 1 | 2 | 3 | 4 | 1c
/* ^^ ^^
[ Clone of the last image ] [ Clone of the 1st image ]
*/
(或left: -100px
or even better (for a matter of performance) margin-left: -100px
),因此滑块可以显示第一张图片。要从图像切换到另一个图像,您需要在之前选择的同一属性上应用javascript动画。
当您的滑块当前位于4 th 图像时,您必须从图像transform: translateX(-100px)
切换到4
,因此我们的想法是在最后执行回调很快就会在真正的1 st 图像偏移处重新定位滑块包装的动画(例如,您将1c
设置为容器)
当滑块当前位于1 st 元素上时,这类似:要显示上一张图像,您只需执行从图像left: -100px
到1
的动画当动画完成后,您只需移动容器,使滑块显然位于4 th 图像偏移处(例如,您将4c
设置为容器)。
你可以看到对上面小提琴的影响:这是我使用的最小left: -400px
代码(当然代码甚至可以优化,所以项目的宽度不会硬编码到脚本中)
js/jquery
如前所述,这个解决方案不需要太多努力和谈论性能,将此方法与普通滑块进行比较而不进行循环,只需要在滑块初始化时进行两次额外的DOM插入(一些非常简单) )管理后向/前向循环的额外逻辑。
我不知道是否存在更简单或更好的方法,但希望无论如何都有帮助。
注意:如果您还需要一个自适应图库,也许this answer可能会有所帮助
答案 1 :(得分:3)
我刚刚创建了项目滑块:检查出来: https://github.com/lingtalfi/jItemSlider/blob/master/README.md
这是600行代码,也许你可以简单地浏览它。
背后的想法受netflix滑块的启发(截至2016-02-24)。
基本上,它使用css变换翻译,因为它们是浏览器中最快/最简单的。
http://eng.wealthfront.com/2015/05/19/performant-css-animations/
现在滑动运动背后的基本概念是,你只显示当前可见的切片, 但你左边还有一个不可见的切片,右边有另一个不可见的切片。
并且,您还有两个额外的项目,每侧一个,以便您的项目如下所示:
之前的项目 - 上一个额外项目 - 主要项目 - 下一个额外项目 - 下一个项目
只有主要项目可见。 额外的项目部分可见。 上一个和下一个项目是不可见的。
此处有更多详情: https://github.com/lingtalfi/jItemSlider/blob/master/doc/conception.md
现在当您向右滑动(例如)时,您基本上会向右侧添加更多项目, 然后从左侧删除它们。
这项技术是我迄今为止遇到的最好的技术,因为你没有处理很长的项目列表(使用 克隆而不删除不可见的项目),这会使你的动画变慢。
注意:我第一次试用这个滑块实际上是克隆而不删除,它可以工作,但我不喜欢它: https://github.com/lingtalfi/jInfiniteSlider
此外,它是基于项目(而不是基于像素),最后,这是用户期望的,因为 一切都始终是一致的,应该是。
答案 2 :(得分:0)
非常感谢这篇文章! 我有更新并使用上面的代码。 我希望这对每个人都有帮助。 可怜的开发者。
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title>Directive slider</title>
<style>
/* 四联切换焦点图 */
.slides-wrapper{ position: relative; width: 100%; margin: 10px 0; }
.gallery { position: relative; width: 1200px; height: 180px; overflow:hidden; }
.gallery ul { font-size: 0; white-space: nowrap; position: absolute; top: 0; left: -1200px; margin: 0; padding: 0; }
.gallery li { display: inline-block; vertical-align: top; width: 1200px; height: 180px; white-space: normal; }
.gallery li img{ width: 298px; height:180px; padding: 1px; }
.gallery .arrow { background: url(/shop/templates/default/images/home_bg.png) no-repeat; background-size: 150px 223px; width: 35px; height: 70px; position: absolute; z-index: 2; top: 50px; cursor: pointer; opacity: 0;}
.gallery .prev { background-position: 1px -92px; left: 0;}
.gallery .next { background-position: -30px -92px; right: 0px;}
</style>
<style type="text/css">
.demo_wrapper{
margin: 0 auto;
width: 1200px;
}
.demo_wrapper .title{
text-align: center;
}
</style>
</head>
<body>
<div class="demo_wrapper">
<div class="title">
<h1>Directive slider (Published by fenmingyu)</h1>
</div>
<!-- demo content -->
<div class="slides-wrapper">
<div class="gallery" id="top_sale_gallery">
<ul>
<li>
<a href="" target="_blank" title="" style="opacity: 1;"><img src="http://imgserv.5thmedia.cn/upload_test/shop/editor/web-102-104-1-1.jpg?234" alt=""></a>
<a href="" target="_blank" title="" style="opacity: 1;"><img src="http://imgserv.5thmedia.cn/upload_test/shop/editor/web-102-104-1-2.jpg?752" alt=""></a>
<a href="" target="_blank" title="" style="opacity: 1;"><img src="http://imgserv.5thmedia.cn/upload_test/shop/editor/web-102-104-1-3.jpg?320" alt=""></a>
<a href="" target="_blank" title="" style="opacity: 1;"><img src="http://imgserv.5thmedia.cn/upload_test/shop/editor/web-102-104-1-4.jpg?365" alt=""></a>
</li>
<li>
<a href="" target="_blank" title="" style="opacity: 1;"><img src="http://imgserv.5thmedia.cn/upload_test/shop/editor/web-102-104-2-1.jpg?852" alt=""></a>
<a href="" target="_blank" title="" style="opacity: 1;"><img src="http://imgserv.5thmedia.cn/upload_test/shop/editor/web-102-104-2-2.jpg?746" alt=""></a>
<a href="" target="_blank" title="" style="opacity: 1;"><img src="http://imgserv.5thmedia.cn/upload_test/shop/editor/web-102-104-2-3.jpg?525" alt=""></a>
<a href="" target="_blank" title="" style="opacity: 1;"><img src="http://imgserv.5thmedia.cn/upload_test/shop/editor/web-102-104-2-4.jpg?550" alt=""></a>
</li>
</ul>
<div class='arrow prev'></div>
<div class='arrow next'></div>
</div>
<div class="gallery" id="top_goods_gallery">
<ul>
<li>
<a href="" target="_blank" title="" style="opacity: 1;"><img src="http://imgserv.5thmedia.cn/upload_test/shop/editor/web-102-104-3-1.jpg?793" alt=""></a>
<a href="" target="_blank" title="" style="opacity: 1;"><img src="http://imgserv.5thmedia.cn/upload_test/shop/editor/web-102-104-3-2.jpg?180" alt=""></a>
<a href="" target="_blank" title="" style="opacity: 1;"><img src="http://imgserv.5thmedia.cn/upload_test/shop/editor/web-102-104-3-3.jpg?550" alt=""></a>
<a href="" target="_blank" title="" style="opacity: 1;"><img src="http://imgserv.5thmedia.cn/upload_test/shop/editor/web-102-104-3-4.jpg?851" alt=""></a>
</li>
<li>
<a href="" target="_blank" title="" style="opacity: 1;"><img src="http://imgserv.5thmedia.cn/upload_test/shop/editor/web-102-104-1-1.jpg?234" alt=""></a>
<a href="" target="_blank" title="" style="opacity: 1;"><img src="http://imgserv.5thmedia.cn/upload_test/shop/editor/web-102-104-1-2.jpg?752" alt=""></a>
<a href="" target="_blank" title="" style="opacity: 1;"><img src="http://imgserv.5thmedia.cn/upload_test/shop/editor/web-102-104-1-3.jpg?320" alt=""></a>
<a href="" target="_blank" title="" style="opacity: 1;"><img src="http://imgserv.5thmedia.cn/upload_test/shop/editor/web-102-104-1-4.jpg?365" alt=""></a>
</li>
<li>
<a href="" target="_blank" title="" style="opacity: 1;"><img src="http://imgserv.5thmedia.cn/upload_test/shop/editor/web-102-104-2-1.jpg?852" alt=""></a>
<a href="" target="_blank" title="" style="opacity: 1;"><img src="http://imgserv.5thmedia.cn/upload_test/shop/editor/web-102-104-2-2.jpg?746" alt=""></a>
<a href="" target="_blank" title="" style="opacity: 1;"><img src="http://imgserv.5thmedia.cn/upload_test/shop/editor/web-102-104-2-3.jpg?525" alt=""></a>
<a href="" target="_blank" title="" style="opacity: 1;"><img src="http://imgserv.5thmedia.cn/upload_test/shop/editor/web-102-104-2-4.jpg?550" alt=""></a>
</li>
</ul>
<div class='arrow prev'></div>
<div class='arrow next'></div>
</div>
<div style="clear: both;"></div>
</div>
</div>
</body>
<script src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
<script type="text/javascript">
$(function() {
$.fn.gallery = function(settings) {
var defaults = {
time: 3000,
direction:1
};
var settings = $.extend(defaults, settings);
var gallery_wrapper = $(this),
gallery = gallery_wrapper.find('ul'),
items = gallery.find('li'),
len = items.length,
current = 1, /* the current item we're looking */
first = items.filter(':first'),
last = items.filter(':last'),
w = gallery.find('li').width(),
triggers = gallery_wrapper.find('.arrow');
var show_slide = function(direction,w){
gallery.animate({ left: "+=" + (-w * direction) }, function() {
current += direction;
/**
* we're cycling the slider when the the value of "current"
* variable (after increment/decrement) is 0 or when it exceeds
* the initial gallery length
*/
cycle = !!(current === 0 || current > len);
if (cycle) {
/* we switched from image 1 to 4-cloned or
from image 4 to 1-cloned */
current = (current === 0)? len : 1;
gallery.css({left: -w * current });
}
});
};
var picTimer = setInterval(function() {
show_slide(settings.direction,w);
},
settings.time);
return this.each(function(){
/* 1. Cloning first and last item */
first.before(last.clone(true));
last.after(first.clone(true));
/* 2. Set button handlers */
triggers.on('click', function() {
if (gallery.is(':not(:animated)')) {
var cycle = false;
settings.direction = ($(this).hasClass('prev'))? -1 : 1;
/* in the example buttons have id "prev" or "next" */
show_slide(settings.direction,w);
}
clearInterval(picTimer);
picTimer = setInterval(function() {
show_slide(settings.direction,w);
},
settings.time);
});
/* hover show arrows*/
show_slide(settings.direction,w);
gallery_wrapper.hover(function() {
$(this).find(".arrow").css("opacity", 0.0).stop(true, false).animate({
"opacity": "0.3"
},
300);
},function(){
$(this).find(".arrow").css("opacity", 0.3).stop(true, false).animate({
"opacity": "0"
},
300);
});
});
};
$('#top_goods_gallery.gallery').gallery();
$('#top_sale_gallery.gallery').gallery({
time: 5000,
direction:-1
});
});
</script>
</html>
te并在我的项目中使用它。