封装好的公共代码:
//Create in 2020/9/11 by LX
//获取元素非行内样式的方法 用法:getStyle(元素,样式名)
function getStyle (ele,prop){
//1.编写主要代码
//如果 元素.currentStyle == undefined 标准浏览器中
if(ele.currentStyle == undefined){
//为了让 别人 在函数外面 也能得到我们获取的属性值 我们要把属性值返回出来
return getComputedStyle(ele)[prop];
}else{
return ele.currentStyle[prop];
}
//2.分析不确定的值 提取出来 作为参数 元素 属性
//3.将参数带入到 函数中
}
//2.封装一个动画函数 可以来回运动 用法:move(元素,属性.终点,步长)
var timer = null;
function move (ele,prop,end,step){
clearInterval(timer);
//1.写入主要代码
//1.设置三要素 准备工作
var start = parseInt(getStyle(ele,prop));
//处理步长
step = end>start ? step : -step;
//2.设置定时器 真正开始运动
timer = setInterval(function(){
//3.走一步的代码
//3.1更新起点
start += step;
//3.3判断到达终点
//当前只判断了 从小走到大 也有可能 从大走到小
//步长是正数 10 并且 起点>=终点 证明到终点
//步长是负数 -10 并且 起点<=终点 证明到终点
if((step>0&&start>=end) || (step<0&&start<=end)){
clearInterval(timer);
start = end;
}
//3.2定位到具体的 位置
ele.style[prop] = start + 'px';
},30)
//2.分析不确定的值 提成参数 元素 属性 终点值 步长
//3.将参数 带入到 函数中
}
//3.缓冲动画函数 bufferMove(元素,{属性名1:终点值,属性名2:终点值....},动画结束执行的函数)
function bufferMove(ele, obj, fun) {
//0.防止定时器的叠加
clearInterval(ele.timer);
//1.设置定时器
ele.timer = setInterval(function () {
//声明一个变量 用来记录 当前所有属性 是否都到达终点 假设大家都到了
var flag = '都到了';
//2.循环 obj对象
for (var key in obj) {//{500,height:500,opacity:0.3}
//获取三要素
//判断 如果是透明度 需要处理
if(key=="opacity"){
var start = parseFloat(getStyle(ele,key))*100;
var end = obj[key]*100;
}else{
var start = parseInt(getStyle(ele,key));
var end = obj[key];
}
var step = (end-start)/10;
//处理步长
step = step>0 ? Math.ceil(step) : Math.floor(step);
//更新起点
start += step;
//判断没有到达终点
if(start!=end){
// clearInterval(ele.timer);
flag = "有人没到";
}
//设置样式
//如果是透明度 要单独处理
if(key=="opacity"){
ele.style[key] = start / 100;
}else{
ele.style[key] = start + 'px';
}
}
//判断一下 flag状态是什么 如果是 都到了 证明大家都到了
if(flag == "都到了"){
clearInterval(ele.timer);//这里动画彻底结束
if(typeof fun=="function"){
fun();
}
}
}, 30)
}
轮播图代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>轮播图</title>
<style>
* {
padding: 0;
margin: 0;
list-style: none
}
#wrap {
width: 960px;
height: 320px;
border: 2px solid red;
margin: 50px auto;
position: relative;
overflow: hidden;
}
#left{
position: absolute;
width: 50px;
height: 50px;
top: 135px;
left: 10px;
font-size: 30px;
}
#right{
position: absolute;
width: 50px;
height: 50px;
top: 135px;
right: 10px;
font-size: 30px;
}
#wrap img {
width: 960px;
height: 320px;
}
#wrap ul {
width: 4800px;
position: absolute;
}
#wrap li {
float: left;
}
#wrap p {
position: absolute;
bottom: 20px;
width: 100%;
text-align: center;
}
#wrap span {
padding: 2px 8px;
background: blue;
color: #fff;
margin-right: 4px;
}
#wrap .active {
background: red;
}
</style>
</head>
<body>
<!--1.可视区:一张图片的大小-->
<div id="wrap">
<!--2.图片列表-->
<ul>
<!-- <li><img src="img/1.jpg" alt=""></li>
<li><img src="img/2.jpg" alt=""></li>
<li><img src="img/3.jpg" alt=""></li>
<li><img src="img/4.jpg" alt=""></li>-->
</ul>
<p>
<!--<span class="active">1</span><span>2</span><span>3</span><span>4</span>-->
</p>
<button id="left"><</button>
<button id="right">></button>
</div>
<script src="./common.js"></script>
<script>
//1.获取元素
var ul = document.querySelector("ul");
var p = document.querySelector("p");
var btns = document.querySelectorAll("button");
var wrap = document.querySelector("#wrap");
//2.动态渲染结构
var imgArr = [
"./img/1.jpg",
"./img/2.jpg",
"./img/3.jpg",
"./img/4.jpg"
];
//3.根据数据 添加li 和 序号span
for(var i=0; i<imgArr.length; i++){
//创建li
var li = document.createElement("li");
li.innerHTML = '<img src="'+imgArr[i]+'" alt="">';
ul.appendChild(li);
//创建span
var span = document.createElement("span");
span.innerHTML = i+1;
p.appendChild(span);
}
var spans = p.children;//获取所有序号span
spans[0].className = "active";
//获取图片宽度
var imgWid = ul.children[0].offsetWidth;
//4.自动轮播
var n = 0;//要显示的图片的索引
function auto(){
n++;
//判断 如果当前已经是假0 并且还要往后走 就直接定位到真0 并向真1 走
if(n>=5){
ul.style.left = 0;
n = 1;
}
//已经在第0张图片 还要向前走 就要立即定位到假0 向最后一张走
if(n<0){
ul.style.left = -4*imgWid + 'px';
n = 3;
}
bufferMove(ul,{left:-n*imgWid});
for(var j=0; j<spans.length; j++){
spans[j].className = "";
}
if(n==4){
spans[0].className = "active";
}else{
spans[n].className = "active";
}
}
var timer = setInterval(auto,3000);
//5.无缝轮播
//放假图片
var fade = ul.children[0].cloneNode(true);
ul.appendChild(fade);
//鼠标移入停止鼠标移出继续
wrap.onmouseover = function(){
clearInterval(timer);
}
wrap.onmouseout = function(){
timer = setInterval(auto,3000)
}
//箭头轮播
//点击右箭头 切换下一张
btns[1].onclick = auto;
//点击左箭头 切换上一张
btns[0].onclick = function(){
n-=2;
auto();
}
//序号轮播
for(var k=0; k<spans.length; k++){
spans[k].idx = k;
spans[k].onclick = function(){
//判断 如果是假0 定位到真0
if(n==4){
ul.style.left = 0;
}
//切换到对应的图片
bufferMove(ul,{left:-this.idx*imgWid});
//让序号亮起
for(var l=0; l<spans.length; l++){
spans[l].className = ""
}
this.className = "active";
//关联自动轮播
n = this.idx;
}
}
</script>
</body>
</html>