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中parentNode,childNodes,children的应用详解
Dec 17 Javascript
JS随机洗牌算法之数组随机排序
Mar 23 Javascript
JavaScript禁止用户多次提交的两种方法
Jul 24 Javascript
JavaScript里 ==与===区别详解
Aug 16 Javascript
用JS中split方法实现彩色文字背景效果实例
Aug 24 Javascript
微信小程序 限制1M的瘦身技巧与方法详解
Jan 06 Javascript
jQuery Validate 相关参数及常用的自定义验证规则
Mar 06 Javascript
es7学习教程之Decorators(修饰器)详解
Jul 21 Javascript
JS实现微信摇一摇原理解析
Jul 22 Javascript
js使用html2canvas实现屏幕截取的示例代码
Aug 28 Javascript
vue解决弹出蒙层滑动穿透问题的方法
Sep 22 Javascript
JS动态图片的实现方法完整示例
Jan 13 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导出csv格式数据并将数字转换成文本的思路以及代码分享
2014/06/05 PHP
PHP简单实现上一页下一页功能示例
2016/09/14 PHP
PHP更安全的密码加密机制Bcrypt详解
2017/06/18 PHP
Javascript中产生固定结果的函数优化技巧
2013/01/16 Javascript
Javascript alert消息换行的方法
2013/08/07 Javascript
node.js中的fs.futimes方法使用说明
2014/12/17 Javascript
轻量级的原生js日历插件calendar.js使用指南
2015/04/28 Javascript
JS克隆,属性,数组,对象,函数实例分析
2016/11/26 Javascript
对象不支持indexOf属性或方法的解决方法(必看)
2017/05/28 Javascript
详解在vue-cli中使用路由
2017/09/25 Javascript
vue地址栏直接输入路由无效问题的解决
2018/11/15 Javascript
js核心基础之构造函数constructor用法实例分析
2019/05/11 Javascript
jquery操作select常见方法大全【7种情况】
2019/05/28 jQuery
使用Karma做vue组件单元测试的实现
2020/01/16 Javascript
JavaScript常用工具函数库汇总
2020/09/17 Javascript
逐行分析鸿蒙系统的 JavaScript 框架(推荐)
2020/09/17 Javascript
javascript实现点击按钮切换轮播图功能
2020/09/23 Javascript
[01:57]2018年度DOTA2最具潜力解说-完美盛典
2018/12/16 DOTA
[36:16]完美世界DOTA2联赛PWL S3 access vs Rebirth 第一场 12.19
2020/12/24 DOTA
一些常用的Python爬虫技巧汇总
2016/09/28 Python
numpy排序与集合运算用法示例
2017/12/15 Python
python中requests和https使用简单示例
2018/01/18 Python
Python语言快速上手学习方法
2018/12/14 Python
选择Python写网络爬虫的优势和理由
2019/07/07 Python
树莓派极简安装OpenCv的方法步骤
2019/10/10 Python
Flask框架请求钩子与request请求对象用法实例分析
2019/11/07 Python
pytorch 实现tensor与numpy数组转换
2019/12/27 Python
python实现密码强度校验
2020/03/18 Python
Python爬虫之Selenium警告框(弹窗)处理
2020/12/04 Python
video.js支持m3u8格式直播的实现示例
2020/05/20 HTML / CSS
施工安全责任书
2014/04/14 职场文书
环境科学专业求职信
2014/08/04 职场文书
乡镇2014法制宣传日活动总结
2014/11/01 职场文书
2015年部门工作总结范文
2015/03/31 职场文书
2015年社区民政工作总结
2015/04/21 职场文书
Springboot中如何自动转JSON输出
2022/06/16 Java/Android