js轮播图效果,透明度渐变实现,超链接总是访问最后一个

昨天学习了轮播图的制作,是定义了动画左右滚动实现的,这需要在最后追加一个列表项,以实现无缝滚动。学完后到小米官网看了一下,发现其轮播图不是滚动效果的,我觉得这个实现起来更简单,可以通过设置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">&lt;</div>  <!-- 左侧按钮 -->
			<div class="arrowRight">&gt;</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;  /*改变层叠顺序*/
}

猜你喜欢

转载自blog.csdn.net/wangyining070205/article/details/124767234