原生js实现轮播图带无缝滚动及自动播放

<!doctype html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>Document</title>
	<style>
		* {
			margin: 0;
			padding: 0;
			list-style: none;
            border: 0;
		}
		.all {
			width: 500px;
			height: 300px;
			margin: 100px auto;
			padding: 7px;
			border: 1px solid #ccc;
			position: relative;
		}
		.screen {
			width: 500px;
			height: 300px;
			position: relative;
			overflow: hidden;
		}
		.screen ul {
            position: absolute;
            left: 0;
            top: 0px;
            width: 3000px;
        }
		.screen li {
			width: 500px;
			height: 300px;
			overflow: hidden;
			float: left;
		}
		.screen ol {
			/*width: 50%;
			height: 30px;*/
			position: absolute;
			bottom: 7px;
			right: 7px;
		}
		.screen ol li {
			width: 30px;
			height: 30px;
			line-height: 30px;
			background-color: #fff;
			margin: 0 1px;
			text-align: center;
			cursor: pointer;
		}
		.screen ol li.current {
			background-color: yellow;
		}
		#slider {
			text-align: center;
			font-weight: bold;
            font-family: '黑体';
            font-size: 30px;
            color: #fff;
			display: none;
			z-index: 1000;
		}
		#prev, #next{
			position: absolute;
			top: 50%;
			transform: translateY(-50%);
			background-color: rgba(0, 0, 0, 0.3);
			width: 30px;
			height: 30px;
			line-height: 30px;
			cursor: pointer;
		}
		#prev {
			left: 0;
		}
		#next {
			right: 0;
		}
	</style>
</head>
<body>
	<div id="box" class="all">
		<div class="screen">
			<ul>
				<li><img src="images/banner1.jpg" alt=""></li>
				<li><img src="images/banner2.jpg" alt=""></li>
				<li><img src="images/banner3.jpg" alt=""></li>
			</ul>
			<ol></ol>
		</div>
		<div id="slider">
			<div id="prev">&lt;</div>
			<div id="next">&gt;</div>
		</div>
	</div>
	
	<script src="js/common.js"></script>
	<script src="js/animate.js"></script>
	<script>
		// 获取元素
		var box = my$('box');
		var screen = box.children[0];
		var ul = screen.children[0];
		var ol = screen.children[1];

		//箭头
		var slider = my$('slider');
		var prev = my$('prev');
		var next = my$('next');

		// 图片的宽度
		var imgWidth = screen.offsetWidth;

		// 动态生成序号
		var liNums = ul.children.length;
		for (var i = 0; i < liNums; i++) {
			var li = document.createElement('li');

			// 给li设置自定义索引 标签中自定义属性值为字符串形式
			li.setAttribute('index', i);

			ol.appendChild(li);
			setInnerText(li, i + 1);
			// if (i === 0) {
		    //   li.className = 'current';
		    // }
		    // 点击ol序号,动态切换图片,点击2,图片向左走过1张图片的宽度
		    li.onclick = liClick;
		}
		function liClick() {
			// 所有li不高亮显示
			for(var i = 0; i < ol.children.length; i++) {
				var li = ol.children[i];
				li.className = '';
			}
			// 当前点击li高亮显示
			this.className = 'current';

			// 动态切换图片,点击2,图片向左走过1张图片的宽度
			// console.log(li.getAttribute('index')); // 字符串类型
			// 获取自定义属性
			var liIndex = parseInt(this.getAttribute('index'));
			animation(ul, -imgWidth * liIndex);

			// 让全局index和liIndex保持一致  否则在点击最后一张图片对应的序号后再点击next按钮,2会高亮显示,因为没有改变163行的全局index值
			index = liIndex;
		}
		// 让序号0高亮显示
		ol.children[0].className = 'current';
		// 鼠标放在图片上显示上一页 上下页
		box.onmouseenter = function () {
			slider.style.display = 'block';
			// 清除定时器
			clearInterval(timerId);
		}
		box.onmouseleave = function () {
			slider.style.display = 'none';
			// 鼠标离开 继续执行自动播放
			timerId = setInterval(function () {
				next.click();
			}, 2000);
		}
		// 上一页 上下页功能实现
		var index = 0;
		next.onclick = function () {
			// 判断是否是克隆的第一张图片,如果是,修改ul的坐标,显示真正的第一张图片
			if (index === liNums) {
				ul.style.left = '0px';
				index = 0;
			}

			index++;
			// if (index < liNums - 1) {
			if (index < liNums) { // 克隆后ul中的li个数多1,点击到最后一张图片的时候还要继续向后走 liNums - 1改为liNums,克隆的图片没有对应的序号,无法执行click(),故将index++;移到if外面
				// animation(ul, -index * imgWidth);  // for遍历去除所有li的高亮 再找到当前点击的index所属的li比较麻烦。点击下一页时,相当于直接点击对应的ol的li,简便方法:用click()模拟人手点击事件
				ol.children[index].click();
			} else {
				// 所有li不高亮显示
				for(var i = 0; i < ol.children.length; i++) {
					var li = ol.children[i];
					li.className = '';
				}
				// 当前点击li高亮显示
				ol.children[0].className = 'current';
				animation(ul, -imgWidth * index);
			}
		}
		prev.onclick = function () {
			// if (index > 0) {
			// 	index--;
			// 	// animation(ul, -index * imgWidth);
			// 	ol.children[index].click();
			// }

			// 图片是第一张的时候,偷偷地将末尾克隆的图片置于可视区域
			if (index === 0) {
				index = liNums;
				ul.style.left = - index * imgWidth + 'px';
			}
			index-- ;
			ol.children[index].click();
		}
		// 无缝滚动
		// 在最后一张图片的后面克隆第一张图片
		var firstLi = ul.children[0];
		var cloneLi = firstLi.cloneNode(true); // true克隆连带内容 false的时候不带内容,默认为false
		ul.appendChild(cloneLi);

		// 自动播放
		var timerId = setInterval(function () {
			next.click();
		}, 2000);
	</script>
</body>
</html>

common.js:

// 通过id获取元素
function my$(element) {
	var el = document.getElementById(element);
	return el;
}

// innerText textContent 兼容性处理
function setInnerText(element, content) {
	if (typeof element.innerText === 'string') {
		element.innerText = content;
	} else {
		element.textContent = content;
	}
}

animate.js:

// 动画封装
// var timerId = null; // 需全局变量
function animation(element, target) {
	// 给每个element增加一个属性timerId,保证定时器标志互不干扰
	if (element.timerId) {
		clearInterval(element.timerId);
		element.timerId = null;
	}
	element.timerId = setInterval(function () {
		// 步距
		var step = 10;
		var current = element.offsetLeft;
		// 如果当前位置 > 目标位置 step < 0
		if (current > target) {
			step = -Math.abs(step);
		}

		// 当前位置和目标位置的差值小于step
		// console.log(Math.abs(current - target));
		// console.log(Math.abs(step));
		if (Math.abs(current - target) <= Math.abs(step)) { 
			// 停止定时器
			clearInterval(element.timerId);
			element.style.left = target + 'px';  // 赋值为目标值
			// 退出函数
			return;
		};
		// 移动盒子
		current += step;
		element.style.left = current + 'px';
	}, 30);
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值