我正在学习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>
答案 0 :(得分:1)
(有关使用OP原始代码的答案,请参阅我的second answer。)
好的..所以我可能有点过分了:))
问题是,当我刚刚开始时,我做的与你一样,用一堆变量来存储进度和当前位置等。
但实际上,所有这些都是不必要的,并且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
的{{3}}超过i++
,但是这样使用没有实际区别。transition:width 0.5s ease 0s;
。与float:left;
一起使幻灯片真正滑动,而不仅仅是静态替换
另一个是background:center center/contain no-repeat;
。这使得图像总是很好地居中并缩放以适合容器。如果图像太宽则会垂直居中,如果图像太高则会水平居中。这就是所有的CSS。<img/>
标签替换为<div>
s,然后再打开那些<div>
将图片设置为background-images
我在这里用HTML做过,这通常被认为是不好的做法,但是如果你将它们移到CSS上,那么你必须为每张幻灯片提供一个唯一的class
或id
。< / LI>
$(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中的编码确实帮助我很好地理解了我在做什么。无论如何,希望我能提供帮助,如果您对代码有任何疑问,请将其留在评论中,我会尽力回答。
答案 1 :(得分:1)
我又看了一眼first answer并意识到这可能完全不是你要找的东西。
所以在这里我尽量保持原始代码的真实性。
请参阅代码段下方的评论以获取解释。
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);};
};
&#13;
<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>
&#13;
$(function() {
变为window.onload = function() {
。var s = document.getElementsByClassName("slide");
。您可以使用它,但由于您已经在一个函数中声明它,并且您通常希望将全局变量保持在最小值(link1,link2),我选择删除全局变量。 var i;
,原因相同。最好在for-loop中声明它们。<button class="change" n="+1">
和".change[n]"
不是我熟悉的,无论是HTML,纯JS还是jQuery。我不认为它可能(如果我错了,有人会纠正我)。id
s - 你已经有了。使用数据属性,那些id
不是必需的。) $(".change[n]").click(function(){
更改为常规函数:function change(n) {
,其中n
包含+1
或-1
的值,用于确定滑块的方向。change(n)
,并沿参数n
发送,值为-1
或+1
。< / LI>
change(n)
中,我删除了var slideIndex = 1;
,因为这会覆盖/干扰您在脚本开头已声明的全局变量var slideIndex
。
不幸的是,这个变量必须保持全局,否则每次调用函数change(n)
时都会重置该值,幻灯片永远不会改变。这是我创建第一个答案的原因之一,以避免全局变量。如果您有兴趣,请查看that one。 var
删除了var stopslider = true;
。 var
创建一个只在函数内可见的新变量(所以不是全局的),但在这种情况下我们需要引用全局var stopslider
,因为这是在内部检查的变量函数slider()
确定是否应该停止自动滑块。 $( "slide1" ).removeClass( "slide" ).addClass( "1slide" );
。我不知道你在那里尝试了什么,但没有必要。 (另外,id
的jQuery选择器需要#
前面的id
,所以:$("#slide1")
)。 id
,因为它们不是必需的,如果您想稍后插入更多幻灯片,它可以为您节省很多痛苦。 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
。全局slideIndex
包含当前幻灯片的值。} else if (slideIndex < 1) {
。因为只有两个子句中的一个可以为真,所以每次调用change(n)
时都无法运行它们。这也直接显示(对于读取代码的程序员)这两个条款属于一起,是一个更大的检查的一部分。} ;
,我删除了它。i
,因此变为:for (var i=0; i<s.length; i++) {
(在函数slider()
中相同)。slider()
,因为我删除了全局var s = document.getElementsByClassName("slide");
,我必须在此函数的顶部添加该行,就像在change(n)
中一样。if (stopslider= true) {
更改为if (stopslider == true) {
由于=
已用于分配值,因此在编程中我们使用==
(double =
)来检查两个值是否相等。timer = setTimeout(slider,4000);
,其中timer
是全局{{1}你在脚本开头设置的
幸运的是,我们实际上并不需要清除计时器。因为var
只运行一次而在此之后才停止,我们只需要不再设置它
为了做到这一点,只需将函数setTimeout()
中的所有代码放在slider()
周围使用的if子句中,只将clearTimeout()
更改为true
:{{1 }}。false
左右,则在您第一次点击按钮后,滑块仍会自动更改一次。) 我更改了图片的if (stopslider == false) {
,这样我们才能真正看到它们发生变化。
setTimeout()
属性的代码段:此代码段基于之前的代码段,只有一些更改。
src
&#13;
data-
&#13;
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"
,因为它们不再需要。 Read about the data-* attribute data-n="+1"
更改为按钮的匿名点击处理程序。id
。change(n)
。(function() { ... })();
从相应按钮获取c[i].onclick = function() {
- 值。var n = parseInt(this.getAttribute("data-n"));
属性中的数据采用文本格式,因此需要n
才能将文本值转换为整数。