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精确统计网站访问量实例代码
Dec 19 Javascript
常用的js验证和数据处理总结
Aug 02 Javascript
Javascript数组中push方法用法分析
Oct 31 Javascript
Bootstrap 3 进度条的实现
Feb 22 Javascript
Bootstrap输入框组件使用详解
Jun 09 Javascript
详解Vuex中mapState的具体用法
Sep 28 Javascript
axios中cookie跨域及相关配置示例详解
Dec 20 Javascript
使用validate.js实现表单数据提交前的验证方法
Sep 04 Javascript
js使用formData实现批量上传
Mar 27 Javascript
详解Vue.directive 自定义指令
Mar 27 Javascript
微信小程序返回上一级页面的实现代码
Jun 19 Javascript
vant-ui AddressEdit地址编辑和van-area的用法说明
Nov 03 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
re0第二季蕾姆被制作组打入冷宫!艾米莉亚女主扶正,原因唏嘘
2020/04/02 日漫
smarty实例教程
2006/11/19 PHP
fleaphp常用方法分页之Pager使用方法
2011/04/23 PHP
php转换颜色为其反色的方法
2015/04/27 PHP
PHP检查网站是否宕机的方法示例
2017/07/24 PHP
PHP goto语句用法实例
2019/08/06 PHP
js弹窗代码 可以指定弹出间隔
2010/07/03 Javascript
Javascript中call的两种用法实例
2013/12/13 Javascript
javascript在子页面中函数无法调试问题解决方法
2014/01/17 Javascript
Javascript中innerHTML用法实例分析
2015/01/12 Javascript
window.onerror()的用法与实例分析
2016/01/27 Javascript
BootStrap智能表单实战系列(九)表单图片上传的支持
2016/06/13 Javascript
JavaScript中的call和apply的用途以及区别
2017/01/11 Javascript
基于JS抓取某高校附近共享单车位置 使用web方式展示位置变化代码实例
2019/08/27 Javascript
VUE实现图片验证码功能
2020/11/18 Javascript
浅谈layui数据表格判断问题(加入表单元素),设置单元格样式
2019/10/26 Javascript
npx create-react-app xxx创建项目报错的解决办法
2020/02/17 Javascript
[11:27]《一刀刀一天》之DOTA全时刻20:TI4总奖金突破920W TS赛事分析
2014/06/18 DOTA
python 排列组合之itertools
2013/03/20 Python
Python的Bottle框架中获取制定cookie的教程
2015/04/24 Python
wxPython定时器wx.Timer简单应用实例
2015/06/03 Python
python动态加载包的方法小结
2016/04/18 Python
Python使用百度翻译开发平台实现英文翻译为中文功能示例
2019/08/08 Python
对python中 math模块下 atan 和 atan2的区别详解
2020/01/17 Python
python获取天气接口给指定微信好友发天气预报
2020/12/28 Python
详解css3中 text-fill-color属性
2019/07/08 HTML / CSS
三星美国官网:Samsung美国
2017/02/06 全球购物
18-35岁旅游团的全球领导者:Contiki
2017/02/08 全球购物
GIVENCHY纪梵希官方旗舰店:高定彩妆与贵族护肤品
2018/04/16 全球购物
老板电器官方购物商城:老板油烟机、燃气灶、消毒柜、电烤箱
2018/05/30 全球购物
荷兰美妆护肤品海淘网站:Beautinow(中文)
2020/11/22 全球购物
软件测试企业面试试卷
2016/07/13 面试题
物业客服专员岗位职责
2013/11/30 职场文书
养生餐厅创业计划书范文
2014/03/26 职场文书
2015小学音乐教师个人工作总结
2015/07/21 职场文书
ubuntu安装jupyter并设置远程访问的实现
2022/03/31 Python