[英]JavaScript - Image slider buttons not working
我正在学习JavaScript。 现在,我想制作一个典型的图像滑块,当页面加载时它会自动启动,如果单击2个按钮(向前和向后)之一,它将停止自动滑块,然后转到我们单击按钮的位置。
但是我正在测试的代码没有使按钮起作用。 我什至使用jQuery尝试使其工作,但没有成功。 我认为我已经一团糟,但这是代码:
$(function() { var slideIndex = 0; var i; var s = document.getElementsByClassName("slide"); var stopslider = false; slider(); $(".change[n]").click(function(){ var slideIndex = 1; var stopslider = true; $( "slide1" ).removeClass( "slide" ).addClass( "1slide" ); $( "slide2" ).removeClass( "slide" ).addClass( "1slide" ); $( "slide3" ).removeClass( "slide" ).addClass( "1slide" ); $( "slide4" ).removeClass( "slide" ).addClass( "1slide" ); var s = document.getElementsByClassName("1slide"); slideslide1Index += n; if (n > s.length) { slideIndex = 1 } if (n < 1) { slideIndex = s.length } ; for (i = 0; i < s.length; i++) { s[i].style.display = "none"; } s[slideIndex-1].style.display = "block"; }); function slider() { for (i = 0; i < s.length; i++) { s[i].style.display = "none"; } slideIndex++; if (slideIndex > s.length) { slideIndex = 1 } s[slideIndex-1].style.display = "block"; setTimeout(slider, 4000); if (stopslider= true) { clearTimeout(slider); } } });
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <a href="imagem1"><img id="slide1" class="slide" src="imagens/imagemcentral1.jpg"></a> <a href="imagem2"><img id="slide2" class="slide" src="imagens/imagemcentral2.jpg"></a> <a href="imagem3"><img id="slide3" class="slide" src="imagens/imagemcentral3.jpg"></a> <a href="imagem4"><img id="slide4" class="slide" src="imagens/imagemcentral4.jpg"></a> <button id="previous" class="change" n="-1">previous</button> <button id="latter" class="change" n="+1">latter</button>
好吧..所以我可能有点过头了:)
问题是,当我刚开始时,我做的和您做的完全一样,只是有一堆变量来存储进度和当前位置等。
但是实际上,所有这些都是不必要的,并且JavaScript具有这种独特性,因为页面上已经存在“物理” DOM结构,并且可以引用它,而不必使用专用变量。 在许多情况下,它们可以充当您的“变量”,并且在许多情况下,它们优于(全局)变量。
无论如何,所以我几乎更改了整个代码,还重命名了过程中的所有内容,去除了<a>
标记等不必要的元素。 您可能需要它们,但我想使代码尽可能简洁,以便于理解:
阅读代码中的注释以了解发生了什么。
忽略CSS,仅用于样式设置。 所有功能都在JS中。
window.onload = function() { function changeSlide(d, id) { var slides = document.getElementById(id).children[0]; for (var i=0,count=slides.children.length; i<count; ++i) { if (slides.children[i].className.indexOf("active") != -1) {var slide=slides.children[i]; break;} //store the current slide } if (d=="next") { if (slides.lastElementChild.className.indexOf("active") != -1) { slides.firstElementChild.className += " active"; //loop around and activate the first slide } else {slide.nextElementSibling.className += " active";} //activate the next slide } else { //prev if (slides.firstElementChild.className.indexOf("active") != -1) { slides.lastElementChild.className += " active"; //loop around and activate the last slide } else {slide.previousElementSibling.className += " active";} //activate the prev slide } slide.className = slide.className.replace(" active",""); //deactivate the current slide } //AUTOMATIC LOOP------------------------------ function timer(id){setTimeout(function(){if (document.getElementById(id).className.indexOf("auto") != -1) {changeSlide("next",id); timer(id);}},4000);} for (var i=0,s=document.getElementsByClassName("slider"),count=s.length; i<count; ++i) {timer(s[i].id);} //create a timer-loop for every slider //EVENT-HANDLERS------------------------------ for (var i=0,s=document.getElementsByClassName("slider"),count=s.length; i<count; ++i) { s[i].onmousedown = function(){return false;}; //otherwise sometimes the space next to the slider gets selected on navigation //click-handlers for prev/next buttons for (var j=0,c=s[i].children.length; j<c; ++j) { if (s[i].children[j].className.indexOf("nav") != -1) { s[i].children[j].onclick = function() { var s = document.getElementById(this.parentNode.id); if (s.className.indexOf("auto") != -1) {s.className = s.className.replace(" auto","");} //stop the automatic loop changeSlide(this.className.split(" ")[1],this.parentNode.id); //prev/next slide ('this.className.split(" ")[1]' returns the second classname) }; } } } };
.slider {display:inline-block; position:relative; width:240px; height:135px; background:#000;} .slider .slides {width:100%; height:100%;} .slider .slides .slide {float:left; width:0; height:100%; background:center center/contain no-repeat; transition:width 0.5s ease 0s;} .slider .slides .slide.active {width:100%;} .slider .nav {position:absolute; top:0; width:15%; min-width:44px; height:100%; background:#888; opacity:0; cursor:pointer;} .slider:hover .nav {opacity:0.3;} .slider .nav.prev {left:0;} .slider .nav.next {right:0;} .slider .nav .btn {position:absolute; top:0; bottom:0; width:34px; height:34px; margin:auto 0; box-sizing:border-box; border:2px solid #ddd; border-radius:999px; background:#555; opacity:0.7; visibility:hidden;} .slider .nav.prev .btn {left:5px;} .slider .nav.next .btn {right:5px;} .slider:hover .nav .btn {visibility:visible;} .slider:hover .nav .btn:hover {border-color:#fff; opacity:1;} .slider .nav .btn .arrow {position:absolute; top:0; bottom:0; width:0; height:0; margin:auto 0; border:10px solid transparent;} .slider .nav.prev .btn .arrow {right:calc(50% - 3px); border-right-color:#ddd;} .slider .nav.next .btn .arrow {left:calc(50% - 3px); border-left-color:#ddd;} .slider .nav.prev .btn:hover .arrow {border-right-color:#fff;} .slider .nav.next .btn:hover .arrow {border-left-color:#fff;}
<div class="slider auto" id="slider1"> <div class="slides"> <div class="slide active" style="background-image:url('https://placeimg.com/320/180/arch');"></div> <div class="slide" style="background-image:url('https://placeimg.com/640/250/animals');"></div> <div class="slide" style="background-image:url('https://placeimg.com/720/450/tech/sepia');"></div> <div class="slide" style="background-image:url('https://placeimg.com/480/480/nature');"></div> </div> <div class="nav prev"><div class="btn"><div class="arrow"></div></div></div> <div class="nav next"><div class="btn"><div class="arrow"></div></div></div> </div> <div class="slider auto" id="slider2"> <div class="slides"> <div class="slide active" style="background-image:url('https://placeimg.com/320/480/nature');"></div> <div class="slide" style="background-image:url('https://placeimg.com/640/480/people/sepia');"></div> <div class="slide" style="background-image:url('https://placeimg.com/640/180/tech');"></div> <div class="slide" style="background-image:url('https://placeimg.com/640/360/arch/sepia');"></div> </div> <div class="nav prev"><div class="btn"><div class="arrow"></div></div></div> <div class="nav next"><div class="btn"><div class="arrow"></div></div></div> </div>
id
并仅使用类来做到这一点。 id
是在.slider
,没有它们我无法在纯JS中工作。 id
,请查看下面的jQuery版本。 for (var i=0; i<slides.children.length; i++) {
做更熟悉的版本,而是在for循环的第一部分中声明了一个额外的变量,因此length
不是在每次迭代中计算。 for (var i=0,count=slides.children.length; i<count; ++i) {
使用++i
与 i++
有细微的区别 ,但是像这样使用时,没有实际区别。 transition:width 0.5s ease 0s;
。 连同float:left;
它使幻灯片真正滑动,而不仅仅是静态替换。 background:center center/contain no-repeat;
。 这使得图像始终可以很好地居中并缩放以适合容器。 如果图像太宽,它将垂直居中;如果图像太高,它将水平居中。 就是CSS。 <img/>
标记替换为<div>
,并在这些<div>
集合上图像作为background-images
。 class
或一个id
。 $(function() { function changeSlide(d, slides) { var slide = $(slides).children(".slide.active")[0]; //store the current slide if (d=="next") { if ($(slides).children(".slide").last().hasClass("active")) { $(slides).children(".slide").first().addClass("active"); //loop around and activate the first slide } else {$(slide).next().addClass("active");} //activate the next slide } else { //prev if ($(slides).children(".slide").first().hasClass("active")) { $(slides).children(".slide").last().addClass("active"); //loop around and activate the last slide } else {$(slide).prev().addClass("active");} //activate the prev slide } $(slide).removeClass("active"); //deactivate the current slide } //AUTOMATIC LOOP------------------------------ function timer(slides){setTimeout(function(){if ($(slides).parent().hasClass("auto")) {changeSlide("next",slides); timer(slides);}},4000);} $(".slider").each(function(){timer($(this).children(".slides")[0]);}); //create a timer-loop for every slider //EVENT-HANDLERS------------------------------ $(".slider").on("mousedown",function(){return false;}); //otherwise sometimes the space next to the slider gets selected on navigation $(".slider .nav").click(function(){ if ($(this).closest(".slider").hasClass("auto")) {$(this).closest(".slider").removeClass("auto");}; //stop the automatic loop changeSlide(this.className.split(" ")[1],$(this).siblings(".slides")[0]); //prev/next slide }); });
.slider {display:inline-block; position:relative; width:240px; height:135px; background:#000;} .slider .slides {width:100%; height:100%;} .slider .slides .slide {float:left; width:0; height:100%; background:center center/contain no-repeat; transition:width 0.5s ease 0s;} .slider .slides .slide.active {width:100%;} .slider .nav {position:absolute; top:0; width:15%; min-width:44px; height:100%; background:#ddd; opacity:0; cursor:pointer;} .slider:hover .nav {opacity:0.3;} .slider .nav.prev {left:0;} .slider .nav.next {right:0;} .slider .nav .btn {position:absolute; top:0; bottom:0; width:34px; height:34px; margin:auto 0; box-sizing:border-box; border:2px solid #ddd; border-radius:999px; background:#555; opacity:0.7; visibility:hidden;} .slider .nav.prev .btn {left:5px;} .slider .nav.next .btn {right:5px;} .slider:hover .nav .btn {visibility:visible;} .slider:hover .nav:hover .btn {opacity:1;} .slider .nav .btn .arrow {position:absolute; top:0; bottom:0; width:0; height:0; margin:auto 0; border:10px solid transparent;} .slider .nav.prev .btn .arrow {right:calc(50% - 3px); border-right-color:#ddd;} .slider .nav.next .btn .arrow {left:calc(50% - 3px); border-left-color:#ddd;} .slider .nav.prev:hover .btn .arrow {border-right-color:#fff;} .slider .nav.next:hover .btn .arrow {border-left-color:#fff;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <div class="slider auto"> <div class="slides"> <div class="slide active" style="background-image:url('https://placeimg.com/320/180/arch');"></div> <div class="slide" style="background-image:url('https://placeimg.com/640/250/animals');"></div> <div class="slide" style="background-image:url('https://placeimg.com/720/450/tech/sepia');"></div> <div class="slide" style="background-image:url('https://placeimg.com/480/480/nature');"></div> </div> <div class="nav prev"><div class="btn"><div class="arrow"></div></div></div> <div class="nav next"><div class="btn"><div class="arrow"></div></div></div> </div> <div class="slider auto"> <div class="slides"> <div class="slide active" style="background-image:url('https://placeimg.com/320/480/nature');"></div> <div class="slide" style="background-image:url('https://placeimg.com/640/480/people/sepia');"></div> <div class="slide" style="background-image:url('https://placeimg.com/640/180/tech');"></div> <div class="slide" style="background-image:url('https://placeimg.com/640/360/arch/sepia');"></div> </div> <div class="nav prev"><div class="btn"><div class="arrow"></div></div></div> <div class="nav next"><div class="btn"><div class="arrow"></div></div></div> </div>
id
,这使得在其他站点上实现更加灵活。 您选择的哪个可能主要取决于偏好。 我个人更喜欢jQuery,因为它使生活变得更加轻松,而且无论如何我已经将它用于其他所有功能。 但是当我刚开始的时候,我真的对此感到怀疑,使用纯JS编码当然可以帮助我更好地了解自己在做什么。 无论如何,希望对我有帮助,如果您对代码有任何疑问,请将'em留在注释中,我会尽力回答。
我再次看了我的第一个答案 ,意识到可能完全不是您想要的。
因此,在这里,我将尽量保持对您原始代码的忠诚。
有关说明,请参见代码段下方的注释。
window.onload = function() { var slideIndex = 0; var stopslider = false; slider(); function change(n) { stopslider = true; var s = document.getElementsByClassName("slide"); slideIndex += n; if (slideIndex > s.length) { slideIndex = 1; } else if (slideIndex < 1) { slideIndex = s.length; } for (var i=0; i<s.length; i++) { s[i].style.display = "none"; } s[slideIndex-1].style.display = "block"; } function slider() { if (stopslider == false) { var s = document.getElementsByClassName("slide"); for (var i=0; i<s.length; i++) { s[i].style.display = "none"; } slideIndex++; if (slideIndex > s.length) { slideIndex = 1; } s[slideIndex-1].style.display = "block"; setTimeout(slider, 4000); } } //CLICK-HANDLERS------------------------- document.getElementById("previous").onclick = function(){change(-1);}; document.getElementById("latter").onclick = function(){change(+1);}; };
<a class="slide" href="imagem1"><img src="https://placeimg.com/200/150/animals"></a> <a class="slide" href="imagem2"><img src="https://placeimg.com/200/150/arch"></a> <a class="slide" href="imagem3"><img src="https://placeimg.com/200/150/people"></a> <a class="slide" href="imagem4"><img src="https://placeimg.com/200/150/tech"></a> <button id="previous" class="change">previous</button> <button id="latter" class="change">latter</button>
$(function() {
成为window.onload = function() {
。 var s = document.getElementsByClassName("slide");
。 您可以使用它,但是由于您也已经在一个函数中声明了它,并且通常希望将全局变量保持为最小值( link1 , link2 ),因此我选择删除全局变量。 var i;
,同样的原因。 最好在for循环中声明它们。 <button class="change" n="+1">
和".change[n]"
。 我认为这是不可能的(如果我错了,请纠正我) 。 id
s-已经拥有它。使用数据属性,则不需要这些id
。) $(".change[n]").click(function(){
更改为常规函数: function change(n) {
,其中n
保留确定方向的+1
或-1
滑块的 change(n)
,并随参数n
一起发送,值-1
或+1
。 change(n)
,我删除了var slideIndex = 1;
因为这会覆盖/干扰您在脚本开始时已经声明的全局变量var slideIndex
。 change(n)
都将重置该值,并且幻灯片将永远不会更改。 这是我创建第一个答案以避免全局变量的原因之一。 如果你有兴趣,请那一个了。 var stopslider = true;
删除了var
var stopslider = true;
。 var
创建一个仅在函数内部可见的新变量(因此在全局内部不可见),但是在这种情况下,我们确实需要引用全局var stopslider
,因为这是在函数slider()
内部检查的变量,以确定是否自动滑块应停止。 $( "slide1" ).removeClass( "slide" ).addClass( "1slide" );
。 我不知道您在那儿尝试什么,但这不是必需的。 (此外,用于id
jQuery选择器需要在id
前面加#
,因此: $("#slide1")
)。 id
,因为它们不是必需的,并且当您以后要插入更多幻灯片时,可以避免很多麻烦。 var s = document.getElementsByClassName("1slide");
删除了1
var s = document.getElementsByClassName("1slide");
,也不知道您在那做什么。 class="slide"
从<img/>
移到了<a>
,因为否则图像将被隐藏,但是所有图像的<a>
仍然可见,这不是您想要的。 <a>
,但是您可能有特定的用途,因此我将其保留。 slideslide1Index += n;
到slideIndex += n;
,因此它引用了全局变量。 n
: if (n > s.length) {
,但是您应该检查slideIndex
。 请记住, n
永远不会具有-1
或+1
的值。 Global slideIndex
保存当前幻灯片的值。 } else if (slideIndex < 1) {
。 因为这两个子句中只有一个是真的,所以每次调用change(n)
时都无法运行它们。 并且这也直接(向阅读代码的程序员显示)这两个子句在一起,是一项较大检查的一部分。 } ;
,我将其删除。 i
,这样就可以: for (var i=0; i<s.length; i++) {
(与函数slider()
相同)。 var s = document.getElementsByClassName("slide");
slider()
内部,因为我删除了全局变量var s = document.getElementsByClassName("slide");
,我必须在该函数的顶部添加该行,就像在change(n)
。 if (stopslider= true) {
更改为if (stopslider == true) {
。 =
已经用于分配值,所以在编程中我们使用==
(double =
)检查两个值是否相等。 timer = setTimeout(slider,4000);
,其中timer
是您在脚本开始时设置的全局var
。 setTimeout()
仅运行一次,然后停止,所以我们无需再次设置它。 slider()
的代码放入您在clearTimeout()
周围使用的if子句中,只需将true
更改为false
: if (stopslider == false) {
。 setTimeout()
周围,则在第一次单击按钮后,滑块仍将自动再更改一次。) 我更改了图片的src
,以便我们可以实际看到它们的更改。
data-
属性的代码段: 此代码段基于上一个代码段,并进行了一些更改。
window.onload = function() { var slideIndex = 0; var stopslider = false; slider(); function slider() { if (stopslider == false) { var s = document.getElementsByClassName("slide"); for (var i=0; i<s.length; i++) { s[i].style.display = "none"; } slideIndex++; if (slideIndex > s.length) { slideIndex = 1; } s[slideIndex-1].style.display = "block"; setTimeout(slider, 4000); } } //CLICK-HANDLERS------------------------- (function() { var c = document.getElementsByClassName("change"); for (var i=0; i<c.length; i++) { c[i].onclick = function() { stopslider = true; var n = parseInt(this.getAttribute("data-n")); var s = document.getElementsByClassName("slide"); slideIndex += n; if (slideIndex > s.length) { slideIndex = 1; } else if (slideIndex < 1) { slideIndex = s.length; } for (var i=0; i<s.length; i++) { s[i].style.display = "none"; } s[slideIndex-1].style.display = "block"; }; } })(); };
<a class="slide" href="imagem1"><img src="https://placeimg.com/200/150/animals"></a> <a class="slide" href="imagem2"><img src="https://placeimg.com/200/150/arch"></a> <a class="slide" href="imagem3"><img src="https://placeimg.com/200/150/people"></a> <a class="slide" href="imagem4"><img src="https://placeimg.com/200/150/tech"></a> <button class="change" data-n="-1">previous</button> <button class="change" data-n="+1">latter</button>
data-n="-1"
和data-n="+1"
,并从按钮中删除了id
,因为不再需要它们了。 阅读有关data- *属性的信息 change(n)
为按钮的匿名单击处理程序。 (function() { ... })();
。 c[i].onclick = function() {
。 var n = parseInt(this.getAttribute("data-n"));
从相应按钮获取n
值。 data-n
属性中的data-n
为文本格式,因此需要parseInt()
将文本值转换为整数。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.