前言
做一下轮播图的效果
正文
1.轮播图实现要求:
页面:
1.视觉窗口,即可见区域
2.包含所有图片的容器
3.具体的每一张轮播图片
4,锚点列表, 点击可跳到具体某一页
5.左右切换按钮
让每一个轮播页大小刚好等于视图窗口大小
1.设置视图窗口宽度, 让超过的部分隐藏
2.设置包含所有图片的容器的宽度为 10000%, 目的是为了让容器足够大. 因为如果容器不够大的话容器中每一张图片就算设定了固定宽度也还是会受到挤压导致一定程度的变形.这里设置的宽度10000%为相对与父div(视图窗口)的100倍, 即100% * 100; 所以这个轮播图最多可装下100个轮播页面
4.设置每一个轮播页面的宽度为父div (容器) 1%, 刚好等于爷爷div (视图窗口) 的大小, 即 100% = 100% * 100 * 1% . 这时视图窗口div中就刚好可见一个轮播页.
页面代码:
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<title>轮播图</title>
<style media="screen">
* {
margin: 0;
padding: 0;
border: 0;
}
#container {
width: 510px;
height: 286px;
margin: 0 auto;
position: relative;
background: pink;
overflow: hidden;
}
#inner {
width: 10000%;/*设置的宽度10000%为相对与视图窗口的100倍*/
height: 100%;
position: absolute;
left: 0px;
top: 0px;
}
#inner img {
width: 1%;
height: 100%;
float: left;
}
.paganation {
width: 100%;
position: absolute;
bottom: 10px;
text-align: center;
}
.paganation span {
padding: 5px 8px;
background: #F2F2F2;
color: red;
border-radius: 50%;
cursor: pointer
}
.paganation .selected {
background: #888;
color: white;
}
.arrow {
position: absolute;
top: 0;
width: 30px;
height: 286px;
line-height: 286px;
text-align: center;
color: white;
cursor: pointer;
}
#right {
right: 0;
}
.arrow:hover {
background: rgba(0, 0, 0, 0.5);
}
</style>
</head>
<body>
<!--视图窗口 -->
<div id="container">
<!-- 包含所有图片的容器 -->
<div id="inner" class="clear">
<img style="background:red;" src="#1#" alt="">
<img style="background:orange;" src="#2#" alt="">
<img style="background:green;" src="#3#" alt="">
<img style="background:cyan;" src="#4#" alt="">
<img style="background:yellow;" src="#5#" alt="">
<img style="background:purple;" src="#6#" alt="">
<img style="background:pink;" src="#7#" alt="">
<img style="background:blue;" src="#8#" alt="">
<img style="background:red;" src="#1#" alt="">
</div>
<div class="paganation" id="paganation">
<!-- 锚点列表 -->
<span class="selected">1</span>
<span>2</span>
<span>3</span>
<span>4</span>
<span>5</span>
<span>6</span>
<span>7</span>
<span>8</span>
</div>
<div id="left" class="arrow">
< <!-- 向左切换按钮 -->
</div>
<div id="right" class="arrow">
> <!-- 向右切换按钮 -->
</div>
</div>
</body>
<script type="text/javascript">
</script>
</html>
js实现
1.改变索引, 添加class使对应锚点设为选中状态
2.计算这次滚动到终点时包含所有图片的容器需要相对与视图窗口左移的位置
3.清空定时器(防止开启多个重名定时器导致图片滚动速度收到影响)
4.开启定时器(刷新速度一般为10~20ms), 每一次将图片移动一定的距离, 直达到达这次移动重点时清空定时器
5.如何让轮播图自动滚动?
设置一个定时器(刷新速度没几秒一次), 每次调用一次轮播的移动函数
6.如何实现无缝轮播(最后一张转到第一张时的衔接)
在最后一张轮播图后复制一份第一张轮播图, 放到最后, 让第一页和最后一页完全相同
最后一张轮播图移动到终点时将包含所有图片的容器的左偏移量设为0, 即最后一张滚动到终点时瞬间将第一张轮播图放置于视图窗口中, 看起来就无缝了
7.让滚动速度为匀减速运动
在定时器中每一次移动距离可以设置为
移动距离 = (终点 - 当前位置) / 15;
js代码:
let container = document.getElementById('container')
let inner = document.getElementById('inner')
let paganation = document.getElementById('paganation')
let spanList = document.getElementById("paganation").getElementsByTagName('span')
let right = document.getElementById('right')
let left = document.getElementById('left')
function Carousel(container, inner, spanList, left, right, speedControl = 15, autoRoll = true, slideCycle = 5000) {
this.container = container; //组件容器, 包括所有
this.inner = inner; //装载图片的容器
this.spanList = spanList; //每页锚点
this.left = left; //左移button
this.right = right; //右移button
this.speedControl = speedControl; //速度控制,值越小轮播跳转速度越快
this.autoRoll = autoRoll; //是否自动滚动
this.slideCycle = slideCycle; //滚动周期
this.timer; //完成滚动的定时器
var me = this
this.distance = this.container.offsetWidth;
console.log(spanList);
if (left && right) {
this.left.onclick = function() {
if (me.clickFlag) {
// clickFlag = false
me.backward()
}
}
this.right.onclick = function() {
if (me.clickFlag) {
// clickFlag = false
me.forward()
}
}
}
for(let i=0; i < this.spanList.length; i++) {
this.spanList[i].onclick= function() {
me.index = i;
me.routate();
}
}
if (this.autoRoll) {
this.timeAutoGo = setInterval(function() {
me.index++
if (this.index == spanList.length) {
me.index = 0
}
me.routate()
}, this.slideCycle)
}
}
Carousel.prototype = {
constructor:Carousel,
index: 0,
clickFlag: true,
routate: function () {
var start=this.inner.offsetLeft;//获取移动块移动前的left的开始坐标, (0,width, width*2, width*3 ...)
var end=this.index*this.distance*(-1);//获取移动块移动结束的坐标。
//计算公式即当移动到第三张图片时,图片下标为2乘以图片的宽度就是块的left值。
var change=end-start;//偏移量
this.clear();//先把按钮状态清除,再让对应按钮改变状态
if(this.index==this.spanList.length){
this.spanList[0].className="selected";
}else{
this.spanList[this.index].className="selected";
}
var me = this;
clearInterval(me.timer);//开启计时器前先把之前的清除, 防止多次重复生成定时器,干扰操作,
me.timer=setInterval(function() {
var iCur = parseInt(me.getStyle(me.inner, 'left'));
if(iCur == end){//当图片到达终点停止计时器
clearInterval(me.timer);
me.clickFlag = false;//当图片到达终点才能切换
if(me.index == me.spanList.length ){
me.inner.style.left = 0; //无缝滚动
me.index=0; //当图片到最后一张时把它瞬间切换回第一张,由于都同一张图片不会影响效果
iCur = 0;
end = 0; //让speed等于0, 即me.inner.style.left = 0;停止此次运动,否则结束时候会向左偏移
}
}
var speed = (end - iCur) / me.speedControl;
speed = speed > 0 ? Math.ceil(speed): Math.floor(speed);
me.inner.style.left = (speed + iCur) + "px"; //每次移动距离=change/maxT*ts
}, 17);//每个17毫秒让块移动
},
forward:function(){
this.index++
if(this.index >this.spanList.length){
this.index = 0
}
this.routate();
},
backward: function(){
this.index--;
//当图片下标到第一张让它返回到倒数第二张,
//left值要变到最后一张才不影响过渡效果
if(this.index<0){
this.index=this.spanList.length-1;
this.inner.style.left=(this.index+1)*this.distance*(-1)+"px";
}
this.routate();
},
//清除页面所有按钮状态颜色
clear : function() {
for(var i=0;i<this.spanList.length;i++){
this.spanList[i].className="";
}
},
getStyle : function(obj, attr) {
if(obj.currentStyle != undefined ){
return obj.currentStyle[attr];
}
else{
return getComputedStyle(obj, false)[attr];
}
}
}
var carousel = new Carousel(container, inner, spanList, left, right, 15, true);
最后
引用自: