纯原生js实现简单可控轮播图

纯原生js实现简单可控轮播图

先说一下实现思路,定义一个相框里面存取着一个具有overflow属性的ul列表,ul列表中存放着若干图片,定义动画来促使照片移动,移动的距离是相框的宽度(imgWidth)*照片索引值(index)
在这里插入图片描述

这里到达最后一张图片要切换到第一张的时候,有一个技巧
就是复制第1张图片的DOM元素并添加到ul列表的最后,例如现在我们有6张图片,当轮播到第6张的时候,那么下一张就是第1张,但当我们添加多一个元素后,实际上显示的是第7张图片,所以这里要加判断如果是第7张图片,就要把索引重置成为第1张图片,即索引值为0

html结构
<div class="box" id="box">
  <div class="inner"><!--相框-->
    <ul>
      <li><a href="#"><img src="image1" /></a></li>
      <li><a href="#"><img src="image2" /></a></li>
      <li><a href="#"><img src="image3" /></a></li>
      <li><a href="#"><img src="image4" /></a></li>
      <li><a href="#"><img src="image5" /></a></li>
      <li><a href="#"><img src="image6" /></a></li>
    </ul>
    <div class="square">
    /*定义默认样式current*/
      <span class="current">1</span>
      <span>2</span>
      <span>3</span>
      <span>4</span>
      <span>5</span>
      <span>6</span>
    </div>
    /*定义左右控件*/
    <div id="focus" style="display: none">
    	<span id="left">&lt;</span><span id="right">&gt;</span>
    </div>
  </div>
</div>
原生js代码
  //获取最外面的div
  let box = document.getElementById("box");
  //获取相框
  let inner = box.children[0];
  //获取相框的宽度
  let imgWidth = inner.offsetWidth;
  //获取ul
  let ulObj=inner.children[0];
  //获取所有的span标签
  let spanObjs=inner.children[1].children;
  let index = 0;
  //循环遍历所有的span标签,注册鼠标进入的事件
  for(let i=0; i < spanObjs.length; i++){
    //循环的时候把索引值保存在每个span的自定义属性中
    spanObjs[i].setAttribute("index", i);
    //注册鼠标进入事件
    spanObjs[i].onmouseover = function () {
      //先干掉所有的span的背景颜色
      for(let j=0; j < spanObjs.length; j++){
        //移除了每个span的类样式
        spanObjs[j].removeAttribute("class");
      }
      //设置当前的span的背景颜色
      this.className = "current";
      //移动ul(每个图片的宽*鼠标放在这个按钮的索引值)
      //获取当前鼠标进入的span的索引
      index = this.getAttribute("index");
      animate(ulObj, -index*imgWidth);
    };
  }
  //添加第1张图片到ul列表的最后
  ulObj.appendChild(ulObj.children[0].cloneNode(true));
  
  //自动播放
  let timeId = setInterval(clickHandle,2000);
	
  //为box注册鼠标进入,鼠标离开的事件,
  //进入时显示控件并停止自动轮播,离开时继续自动播放
  box.onmouseover = function(){
  	 document.getElementById('focus').style.display = "block";
  	 clearInterval(timeId);
  };
  box.onmouseout = function(){
  	 document.getElementById('focus').style.display = "none";
  	 timeId = setInterval(clickHandle,2000);
  };

  //左右焦点按钮
  document.getElementById('right').onclick = clickHandle;
   
  function clickHandle(){
  //当是最后一张时,要把图片重置回第一张,同时将ul列表移动置最开始的位置,以便接下来轮播第2张
  	if(index == ulObj.children.length - 1){
  		index = 0;
  		ulObj.style.left = 0+'px';
  	}
  		//如果不是最后一张,那就++
  		index++;
  		//根据索引值移动ul
  		animate(ulObj,-index*imgWidth);
  		//如果index=6,显示的是第七张图片,用户看来是第一张(第一个小按钮有样式)
  		if(index == ulObj.children.length - 1){
  			spanObjs[0].className = 'current';
  			spanObjs[spanObjs.length-1].className = '';
  		}else{
  			for(let j=0;j < spanObjs.length;j++){
		        //移除了每个span的类样式
		        spanObjs[j].removeAttribute("class");
		    }
		      //设置当前的span的背景颜色
		      spanObjs[index].className = 'current';
		  	}
  	};
   //左边按钮
   document.getElementById('left').onclick = function(){
   //当是第一张图片时点击左控件应当是跳到最后1张
   //此时这里最后一张还是我们第一张图片,即上面添加的DOM元素,就是为了平缓过渡到真实的最后1张图
  	if(index == 0){
  		index=ulObj.children.length-1;
  		//先转移到虚拟上的最后1张
  		ulObj.style.left = -index * imgWidth + "px";
  	}
  		//再-- 平缓过渡到实际上的最后一张图
  		index --;
  		animate(ulObj,-index*imgWidth);
  	for(let j=0; j < spanObjs.length; j++){
		//移除了每个span的类样式
		spanObjs[j].removeAttribute("class");
	}
		//设置当前的span的背景颜色
		spanObjs[index].className = 'current';
  };
	
  	//设置任意的一个元素,移动到指定的目标位置
  	function animate(element, target) {
  		//点击一次就清除一次定时器,这里是为了解决多次点击之后速度更变的问题。
	    clearInterval(element.timeId);
	    //定时器的id值存储到对象的一个属性中
	    element.timeId = setInterval(function () {
	      //获取元素的当前的位置,数字类型
	      var current = element.offsetLeft;
	      //每次移动的距离
	      var step = 50;
	      step = current < target ? step : -step;
	      //当前移动到位置
	      current += step;
	      if (Math.abs(current - target) > Math.abs(step)) {
	        element.style.left = current + "px";
	      } else {
	        //清理定时器
	        clearInterval(element.timeId);
	        //直接到达目标
	        element.style.left = target + "px";
	      }
	    }, 15);
	  }
最后是css样式,大家直接复制就ok,都是很简单的一些样式
* {
  margin: 0;
  padding: 0
}
ul {
  list-style: none
}
img {
  vertical-align: top;
  width: 730px;
  height: 454px;
}
.box {
  width: 730px;
  height: 454px;
  margin: 100px auto;
  padding: 5px;
  border: 1px solid #ccc;
}
.inner {
  width: 730px;
  height: 454px;
  overflow: hidden;
  position: relative;
}
.inner ul {
  width: 1000%;
  position: absolute;
  top: 0;
  left: 0;
}
.inner li {
  float: left;
}
.square {
  position: absolute;
  right: 10px;
  bottom: 10px;
}
.square span {
  display: inline-block;
  width: 16px;
  height: 16px;
  background-color: #fff;
  text-align: center;
  line-height: 16px;
  cursor: pointer;
}
.square span.current {
  background-color: orangered;
  color: #fff;
}
#focus span{
	background-color: rgba(0,0,0,0.3);
	color:white;
	font-size:40px;
	text-align: center;
	width: 40px;
	height: 70px;
	line-height: 60px;
	position: absolute;
	top: 50%;
	margin-top: -35px;
	cursor:pointer;
}
#left{
	float: left;
}
#focus  #right{
	float:right;
	right: 0;
}

看懂记得点个小赞哦,纯手写,献上小弟的膝盖!!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值