昨天学习了轮播图的制作,是定义了动画左右滚动实现的,这需要在最后追加一个列表项,以实现无缝滚动。学完后到小米官网看了一下,发现其轮播图不是滚动效果的,我觉得这个实现起来更简单,可以通过设置display或opacity属性实现。
我先用了display属性,采用绝对定位,把几张图片重叠在一起,所有列表项初始状态为none,第一项的初始状态为block,当点击某个小圆点时,使用排他思想,所有项状态为display:none,当前项为display:block。程序正常运行了。
我又想把css属性换成不透明度opacity,让当前的图片不透明,其他图片透明,效果和display应该是差不多的。
根据这个思路,我又修改了display的代码,把display换成opacity,我自认为逻辑思路很对,可最后运行的时候,除了第一张正常显示,其余两张都不显示,是空白。可查看运行状态,当前项又确实是不透明的,可就是显示不出来。
我很奇怪,display可以,为什么opacity不可以呢,理论上不是效果差不多的吗?
于是开始排错,可是控制台显示没有错误,小圆点的变化正常。先看js代码,没错,再看html结构,没问题,找了一个上午,最后才发现是css的问题,列表项的定位一定要设置成absolute,我设置了,但是我不小心把position这个单词敲错了,漏了一个字符i,变成了postion,导致列表项没有绝对定位,我这个郁闷啊,耽误了一上午的时间。
问题的关键在于,display和opactiy虽然都是不可见,但是display直接不占用空间,所以是否绝对定位对结果没有影响,opacity虽然也不可见,但是还占用着空间,所以绝对定位对结果是有影响的。绝对定位因为出错未生效,导致几个列表项没有重叠,所以第1张后的图片的位置不是(0,0),而是在图片的下方,被overflow:hidden隐藏掉了。
下面是运行正常的代码,这回可长记性了。
1.rotation.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>轮播图-透明度实现</title>
<link rel="stylesheet" href="css/rotation.css">
<script src="js/rotate.js" charset="utf-8"></script>
</head>
<body>
<div class="focus">
<ul class="carousel"> <!-- 轮播图列表 -->
<li class="opa"><a href="#"><img src="images/1.jpg" alt=""></a></li>
<li><a href="#"><img src="images/2.jpg" alt=""></a></li>
<li><a href="#"><img src="images/3.jpg" alt=""></a></li>
</ul>
<div class="arrowLeft"><</div> <!-- 左侧按钮 -->
<div class="arrowRight">></div> <!-- 右侧按钮 -->
<ol class="disc">
</ol>
</div>
</body>
</html>
2.rotation.css文件
* {
margin: 0;
padding: 0;
}
ul,ol,li {
list-style: none;
}
.focus {
position: relative;
width: 1000px;
height: 375px;
margin: 10px auto;
overflow: hidden;
}
.carousel {
position: absolute;
width: 100%;
left: 0px;
top: 0px;
}
.carousel li {
position: absolute; /*绝对定位*/
top: 0px;
left: 0px;
opacity: 0;
transition: all 1s; /*设置切换时过渡效果*/
}
.carousel li.opa {
/*li和.opa之间,无空格*/
opacity: 1;
}
.carousel li img {
width: 1000px;
height: 375px;
}
.focus div {
display: none;
position: absolute;
top: 50%;
transform: translate(0, -50%); /*上移,使垂直居中*/
width: 36px;
height: 40px;
line-height: 40px;
text-align: center;
color: #fff;
font-size: 36px;
z-index: 99;
cursor: pointer;
}
.arrowLeft {
left: 10px;
}
.arrowRight {
right: 10px;
}
.arrowLeft:hover,.arrowRight:hover {
background-color: rgba(128, 128, 128, .5);
}
.disc {
position: absolute;
bottom: 10px;
right: 50px;
z-index: 99;
}
.disc li {
display: inline-block;
width: 8px;
height: 8px;
background-color: #ccc;
margin: 0 3px;
border-radius: 50%;
cursor: pointer;
}
.disc li.current {
/*li和.current之间,无空格*/
background-color: #f00;
}
3.rotate.js文件
window.addEventListener('load', function () {
var focus = document.querySelector('.focus');
var arrowLeft = document.querySelector('.arrowLeft');
var arrowRight = document.querySelector('.arrowRight');
//鼠标移动到轮播图,左右箭头显示
focus.addEventListener('mouseover', function() {
arrowLeft.style.display = 'block';
arrowRight.style.display = 'block';
clearInterval(timer); //清除定时器
timer = null;
})
focus.addEventListener('mouseout', function() {
arrowLeft.style.display = 'none';
arrowRight.style.display = 'none';
timer = setInterval(function() {
//鼠标离开,开启定时器
arrowRight.click();
}, 3000);
})
var ul = focus.querySelector('ul');
var ol = focus.querySelector('ol');
var num=ul.children.length;
var disc = 0;
//动态生成小圆点
for (let i = 0; i < num; i++) {
var li = document.createElement('li');
ol.appendChild(li);
li.addEventListener('click', function() {
for (let k = 0; k < num; k++) {
ol.children[k].className = '';
ul.children[k].className = '';
}
this.className = 'current';
ul.children[i].className = 'opa';
disc = i;
})
}
ol.children[0].className ='current';
//点击右侧箭头
arrowRight.addEventListener('click', function() {
disc++; //圆点样式
if (disc == num) {
disc = 0;
}
for (let k = 0; k < num; k++) {
ol.children[k].className = '';
ul.children[k].className = '';
}
ol.children[disc].className = 'current';
ul.children[disc].className = 'opa';
})
// 点击左侧按钮
arrowLeft.addEventListener('click', function() {
disc--;
if (disc < 0) {
disc = num - 1;
}
for (let k = 0; k < num; k++) {
ol.children[k].className = '';
ul.children[k].className = '';
}
ol.children[disc].className = 'current';
ul.children[disc].className = 'opa';
})
//自动播放,像点击右侧按钮
var timer = setInterval(function() {
arrowRight.click();
}, 3000);
})
测试代码的时候,发现使用opacity有过渡效果,使用display的时候,transition好像不起作用,怀疑transition对display:none无效,去查找了一下,果然如此。
display:none的时候,页面文档流中将不会存在该元素,display:block的时候,文档流中才存在该元素。transition属性无法对一个从无到有的元素进行过渡显示。
看来要有渐变效果,只能用opacity了。
做到这一步,我以为万事ok了,结果我给3张图片分别加了超链接以后,问题来了,点击访问的时候总是访问最后一个超链接。我在控制台中查看代码,超链接无误。那这是什么原因造成的呢?为什么使用display就不存在这个问题呢?
在这儿纠结了好久,不明白原因,到网上找答案,一开始没找到,不死心,换了关键词,继续找,果然网上有高手,有一个答案相当靠谱,简而言之就是opacity透明时,虽然看不见,但依然存在,有3张透明的纸摞在一块,如果z-index相同的时候,第3张在最上面,我们虽然透过它看到了第1张或第2张,但是点击的时候,还是点击的最上面。所以,这个问题的 解决方案是,当opacity为0时,还需增加css属性visibility: hidden;当opacity:为1时,增加visibility: visible,这样超链接就不会受影响了,同时还具备渐变效果。
.carousel li {
position: absolute; /*绝对定位*/
top: 0px;
left: 0px;
opacity: 0;
transition: opacity 1s;
visibility: hidden; /*设为不可见*/
}
.carousel li.opa {
/*li和.opa之间,无空格*/
opacity: 1;
visibility: visible; /*设为可见*/
}
另外,既然找到了原因,除了设置不可见,修改z-index值也是可以的。
.carousel li {
position: absolute; /*绝对定位*/
top: 0px;
left: 0px;
opacity: 0;
transition: opacity 1s;
z-index:0;
}
.carousel li.opa {
/*li和.opa之间,无空格*/
opacity: 1;
z-index:1; /*改变层叠顺序*/
}