JavaScript Dom实现轮播图原理和实例


Posted in Javascript onFebruary 19, 2021

想要制作一个轮播图我们要先弄清楚他的原理,如何能让图片自右向左滑动?
让我们想一想生活中有没有类似的东西,比如电影胶片。
我们可以创建一个块作为投影区,创建一个列表作为底片并使其向左移动,达到轮播图效果。

JavaScript Dom实现轮播图原理和实例

创建一个块和列表

创建一个块作为总的容器和显示区域。

<div id="out">
 <ul id="imgList">
 <li><img src="pto/many.jpg" ></li>
 <li><img src="pto/hello.jpg" ></li>
 <li><img src="pto/timg.jpg" ></li>
 <li><img src="pto/zhenjing.jpg"></li>
 </ul>
</div>

现在图片竖着堆在一列,块也不知道在哪里,那添加一点样式

开启定位并令其居中,并且让块大一点并添加背景好确定位置(本实验图片统一宽高比500*431,所以div宽高比520*451)

去掉列表默认样式让列表横着显示

*{
 margin: 0;
 padding: 0;
 }
 #out{
  width:520px;
  height:451px ;
  background-color: #00bcd4;
 position: relative;
 margin: 50px auto;
 /*overflow: hidden;*/
 /*剪掉我们不需要的部分,为了方便调试注掉了*/
 }

 #imgList{
  list-style: none;
  position: absolute;
  /* left: -520px; */
 }
 #imgList li{
  float:left;
  margin: 10px;
}

在尝试浮动后图片依旧是一列,是因为lu的宽度太小放不下,所以我们要扩大,但是我们不能直接决定他的宽度因为随着图片的增加,宽度应不断变大,于是我们用JavaScript来解决宽度
每增加一张图片扩大520px宽度

window.onload=function () {
 // 动态的ul长度
 var imgList = document.getElementById("imgList");
 var imgArr = document.getElementsByTagName("img");
 imgList.style.width=520*imgArr.length+"px";
 }//onload

现在,装载图片的胶片ul每向左偏移-520px就会更换一个图片

导航栏

轮播图会定时更换,但是有可能你的客户刚刚被吸引就已经更换图片了,如果你想让你的客户干巴巴的瞪着图片回来,你很可能失去她。
所以一个完整的轮播图还需要一个能手动切换前后的按钮或一个导航条。
我们这里用几个超链接完成任务

<div id="navDiv">
 <a href="javascript:;"></a>
 <a href="javascript:;"></a>
 <a href="javascript:;"></a>
 <a href="javascript:;"></a>
</div>

ul在开启绝对定位后脱离文档流,现在我们的导航因为没有内容缩成一团挤在左上角
我们要让每一个超联接彼此分开,手动撑开空间,调整到靠下的位置,下方正中或靠右是比较好的选择.
调整透明度降低导航对于人的吸引力,毕竟图片才是主题。
而位置的调整为了便于扩充我们还是要用js来解决。

}
 #navDiv{
  position: absolute;
  bottom: 15px;
 }
 #navDiv a{
  float: left;
  width: 15px;
  height: 15px;
  background-color: #89ff00;
  margin: 0 5px;
  opacity: 0.5;
 }
//动态导航居中
 var navDiv = document.getElementById("navDiv");
 var out = document.getElementById("out");
 
 //将纵向剩余距离分到导航左右达到居中效果
 //不除以二就会变成右对齐
 //不要忘了单位,嗯。。可能只有我会忘吧
 navDiv.style.left = (out.clientWidth - navDiv.clientWidth)/2+"px";

导航功能完善

一仅仅个15px大的方块要给用户怎样的反馈?
当前图片所处位置,当鼠标移动到导航是时要反馈信息告诉用户我是可以点击的,点击导航能切换图片。

#navDiv a:hover{
  background-color: red;
  /* 鼠标移入效果*/
 /* 内联样式的优先级很高注意不要被覆盖失效*/
 }
//定位效果
var allA = document.getElementsByTagName("a");
var index = 0;
 allA[index].style.backgroundColor="black";

 //点击导航效果
 //使用块级作用域let,不然i会是同一个数
 for(let i=0;i<allA.length;i++){
  allA[i].onclick=function () {
  imgList.style.left=-520*i+"px";

  //清除内联样式,使得css文件能生效
  allA[index].style.backgroundColor="";
  index=i;
  allA[index].style.backgroundColor="black";
  }
 }

动画效果

为什么要做动画? (因为很酷(?ω?*)♪ )

因为没有轮播效果不叫轮播图,明明更改地址就能完成,忙活半天不就是为了这个,用最大的标题告诉你动画才是轮播图的精髓所在

主要思路是利用定时器让本来一部完成的效果多次完成,到达指定位置关闭定时器。

要注意的问题

每次移动距离与图片大小可能除余,导致停止位置不准确(大于或小于)或无法停止(不能刚好到达停止位置),小的误差会逐渐积累。
在定时器打开前关闭上一个计时器,否则在一个动画未完成前点击另一个会发生鬼畜现象

//点击导航效果
 for(let i=0;i<allA.length;i++){
  allA[i].onclick=function () {
  move(imgList,-520*i,10);
  // imgList.style.left=-520*i+"px";
  //换掉这个很low的过场
  allA[index].style.backgroundColor="";
  index=i;
  allA[index].style.backgroundColor="black";
  }
 }
 
function move(obj,target,speed) {//元素;目标位置;速度
  //每次触发事件关闭上一个定时器
  //这里是重点,你可以去掉这一句后随意点一下关差效果
  clearInterval(obj.timer);
  
  var current = parseInt(window.getComputedStyle(obj,null).left);
  //获得当前位置
  //判断运动方向
  if(target<current){
  speed = -speed;
  }
  //定时器标识
  obj.timer = window.setInterval(function () {
  //m每次开始获取一下当前位置
  var oldValue = parseInt(window.getComputedStyle(obj,null).left);
  //移动并在指定位置停下
  var newValue = oldValue + speed;
  //调整一下停止位置,小的误差会随时间无限放大
  if((speed < 0 && newValue < target)||(speed > 0 && newValue > target)){
   newValue = target;
  }
  imgList.style.left =newValue+"px";
  if(newValue == target){
   clearInterval(obj.timer);
  }

  },30);

 }
change();
 //自动轮播
 //一个定时器用于定时调用
 function change() {
  setInterval(function () {
  index++;
  index=index % imgArr.length ;
  console.log(imgArr.length);
  console.log(index);
  move(imgList,-520*index,20);
  for(let i=0;i<allA.length;i++){
   allA[i].style.backgroundColor="";
   allA[index].style.backgroundColor="black";
  }
  },3000);
 }

这样已经能做到轮播的基本功能,但在最后一张图片切换第一张图片时会向左拉过全部图片,这非常的不酷,我们要让轮播图持续向左循环怎么办?

假设我们要对图a和图b两个图轮播

我们可以结尾插入一个与图a一样的图
在两张图轮播完后转入第三张图让人误认为是第一张图片
在第三张图完成轮播后瞬间跳转至第一张继续轮播,此为瞒天过海之计

JavaScript Dom实现轮播图原理和实例

对于轮播图我们其实只需要知道原理,且不说框架,jquery完成轮播图都不要单纯手撸的十分之一的精力。

完整代码

<!DOCTYPE html>
<html lang="en">
<head>
 <meta charset="UTF-8">
 <title>Title</title>
 <style>
 *{
  margin: 0;
  padding: 0;
 }
 #out{
  width:520px;
  height:451px ;
  margin: 50px auto;
  background-color: #00bcd4;
  position: relative;
  overflow: hidden;
 }

 #imgList{
  list-style: none;
  position: absolute;
 }
 #imgList li{
  float:left;
  margin: 10px;
 }
 #navDiv{
  position: absolute;
  bottom: 15px;
 }
 #navDiv a{
  float: left;
  width: 15px;
  height: 15px;
  background-color: #89ff00;
  margin: 0 5px;
  opacity: 0.5;


 }
 #navDiv a:hover{
  background-color: red;
 /* 内联样式的优先级很高在触发一次后覆盖失效*/
 }

 </style>
</head>
<body>
<div id="out">
 <ul id="imgList">
 <li><img src="pto/many.jpg" ></li>
 <li><img src="pto/hello.jpg" ></li>
 <li><img src="pto/timg.jpg" ></li>
 <li><img src="pto/zhenjing.jpg"></li>
 <li><img src="pto/many.jpg" ></li>
 </ul>
 <div id="navDiv">
 <a href="javascript:;" ></a>
 <a href="javascript:;" ></a>
 <a href="javascript:;" ></a>
 <a href="javascript:;" ></a>
 </div>
</div>
<script>
 window.onload=function () {
 // 动态的ul长度
 var imgList = document.getElementById("imgList");
 var imgArr = document.getElementsByTagName("img");
 imgList.style.width=520*imgArr.length+"px";

 //动态导航居中
 var navDiv = document.getElementById("navDiv");
 var out = document.getElementById("out");
 navDiv.style.left = (out.clientWidth - navDiv.clientWidth)/2+"px";

 //定位效果
 var allA = document.getElementsByTagName("a");
 var index = 0;
 allA[index].style.backgroundColor="black";

 //点击导航效果
 for(let i=0;i<allA.length;i++){
  allA[i].onclick=function () {
  move(imgList,-520*i,20);
  setA();
  // imgList.style.left=-520*i+"px";
  // allA[index].style.backgroundColor="";
  // index=i;
  // allA[index].style.backgroundColor="black";
  }
 }

 // 动画效果
 function move(obj,target,speed,callback) {//元素;目标位置;速度;回调函数
  clearInterval(obj.timer);
  var current = parseInt(window.getComputedStyle(obj,null).left);
  //获得当前位置
  //判断运动方向
  if(target<current){
  speed = -speed;
  }
  //定时器标识
  obj.timer = window.setInterval(function () {
  //m每次开始获取一下位置
  var oldValue = parseInt(window.getComputedStyle(obj,null).left);
  //移动并在指定位置停下
  var newValue = oldValue + speed;
  //调整一下停止位置,小的误差会随时间无限放大
  if((speed < 0 && newValue < target)||(speed > 0 && newValue > target)){
   newValue = target;
  }
  imgList.style.left =newValue+"px";
  if(newValue == target){
   clearInterval(obj.timer);
   callback();
  }

  },30);

 }
 change();
 //自动轮播
 //一个定时器用于定时调用
 function change() {
  setInterval(function () {
  index++;
  index=index % imgArr.length ;
  move(imgList,-520*index,20,function () {
   if(index>=imgArr.length-1 ){
   imgList.style.left =0;
   }
   setA();
  });

  },3000);
 }
 function setA() {
  for(let i=0;i<allA.length;i++){
  allA[i].style.backgroundColor="";
  allA[index].style.backgroundColor="black";

  }
 }
 }//onload
</script>
</body>
</html>

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
javascript 在网页中的运用(asp.net)
Nov 23 Javascript
jquery.ui.draggable中文文档
Nov 24 Javascript
推荐40个简单的 jQuery 导航插件和教程(下篇)
Sep 14 Javascript
jquery实现pager控件示例
Apr 09 Javascript
一个简单的实现下拉框多选的插件可移植性比较好
May 05 Javascript
详解AngularJS中的表格使用
Jun 16 Javascript
js实现带有介绍的Select列表菜单实例
Aug 18 Javascript
D3.js实现饼状图的方法详解
Sep 21 Javascript
webpack常用配置项配置文件介绍
Nov 07 Javascript
Node.js中process模块常用的属性和方法
Dec 13 Javascript
解决vue-cli脚手架打包后vendor文件过大的问题
Sep 27 Javascript
js实现全选和全不选功能
Jul 28 Javascript
JavaScript使用setTimeout实现倒计时效果
Feb 19 #Javascript
react项目从新建到部署的实现示例
Feb 19 #Javascript
原生JavaScript实现幻灯片效果
Feb 19 #Javascript
JavaScript 实现继承的几种方式
Feb 19 #Javascript
JavaScript 生成唯一ID的几种方式
Feb 19 #Javascript
JavaScript实现打字游戏
Feb 19 #Javascript
JS+CSS实现动态时钟
Feb 19 #Javascript
You might like
用PHP 4.2书写安全的脚本
2006/10/09 PHP
php中批量替换文件名的实现代码
2011/07/20 PHP
PHP attributes()函数讲解
2019/02/03 PHP
Javascript操作cookie的函数代码
2012/10/03 Javascript
JS中的prototype与面向对象的实例讲解
2013/05/22 Javascript
flash调用js中的方法,让js传递变量给flash的办法及思路
2013/08/07 Javascript
JS跨域问题详解
2014/11/25 Javascript
浅谈javascript回调函数
2014/12/07 Javascript
node.js中的http.response.writeHead方法使用说明
2014/12/14 Javascript
js实现支持手机滑动切换的轮播图片效果实例
2015/04/29 Javascript
JS基于面向对象实现的放烟花效果
2015/05/07 Javascript
理解 JavaScript Scoping &amp; Hoisting(二)
2015/11/18 Javascript
Javascript打印局部页面实例
2016/06/21 Javascript
微信小程序 action-sheet底部菜单详解
2016/10/27 Javascript
jquery请求servlet实现ajax异步请求的示例
2017/06/03 jQuery
AngularJS 中ui-view传参的实例详解
2017/08/25 Javascript
在vue中给列表中的奇数行添加class的实现方法
2018/09/05 Javascript
使用vue-router与v-if实现tab切换遇到的问题及解决方法
2018/09/07 Javascript
详解ESLint在Vue中的使用小结
2018/10/15 Javascript
小程序实现人脸识别功能(百度ai)
2018/12/23 Javascript
微信小程序云开发获取文件夹下所有文件(推荐)
2019/11/14 Javascript
JS window对象简单操作完整示例
2020/01/14 Javascript
python列表去重的二种方法
2014/02/14 Python
Python实现接受任意个数参数的函数方法
2018/04/21 Python
Python3.6实现连接mysql或mariadb的方法分析
2018/05/18 Python
python 3.7.0 下pillow安装方法
2018/08/27 Python
解决pycharm下os.system执行命令返回有中文乱码的问题
2019/07/07 Python
完美解决keras 读取多个hdf5文件进行训练的问题
2020/07/01 Python
python中zip()函数遍历多个列表方法
2021/02/18 Python
GLAMGLOW格莱魅美国官网:美国知名的面膜品牌
2016/12/31 全球购物
物流仓管员岗位职责
2013/12/04 职场文书
2015年考研复习计划
2015/01/19 职场文书
面试通知短信
2015/04/20 职场文书
2015年社区教育工作总结
2015/05/13 职场文书
SpringDataJPA实体类关系映射配置方式
2021/12/06 Java/Android
一文搞懂Redis中String数据类型
2022/04/03 Redis