DOM动画效果开发
我们先来学习函数节流
函数节流
示例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
#box {
width: 200px;
height: 200px;
background-color: thistle;
position: absolute;
top: 200px;
left: 0;
transition: left .3s ease-in;
}
</style>
</head>
<body>
<button>点击运行动画</button>
<div id="box"></div>
<script>
var btn = document.querySelector('button');
var box = document.getElementById('box');
var pos = 1; // 盒子所在的位置
btn.onclick = function () {
if (pos == 1) {
box.style.left = 1000 + 'px';
pos = 2;
} else if (pos == 2) {
box.style.left = 0 + 'px';
pos = 1;
}
};
</script>
</bod
</html>
如果用户疯狂的点击运行,动画就会没有目的的执行,这时我们需要用到
函数节流
改进后:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
#box {
width: 200px;
height: 200px;
background-color: thistle;
position: absolute;
top: 200px;
left: 0;
transition: left .5s ease-in;
}
</style>
</head>
<body>
<button>点击运行动画</button>
<div id="box"></div>
<script>
var btn = document.querySelector('button');
var box = document.getElementById('box');
var pos = 1; // 盒子所在的位置
var lock = true;
btn.onclick = function () {
if (!lock) return;
if (pos == 1) {
box.style.left = 1000 + 'px';
pos = 2;
} else if (pos == 2) {
box.style.left = 0 + 'px';
pos = 1;
}
lock = false;
setTimeout(function () {
lock = true;
},500);
};
</script>
</body>
</html>
改进过后,即使疯狂点击,也不会出现bug了。
无缝连续滚动特效
原理
克隆一份需要滚动的图片
这个不需要在HTML代码中加动画过渡(transition)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
* {
margin: 0;
padding: 0;
list-style: none;
}
div {
width: 1200px;
margin-top: 30px;
margin-left: 30px;
border: 1px solid #333;
overflow: hidden;
}
ul {
width: 3000px;
position: relative;
left: 0;
}
ul li {
float: left;
}
ul li img {
width: 200px;
vertical-align: top;
}
</style>
</head>
<body>
<div>
<ul>
<li><img src="./images/logo_img_0.png" alt=""></li>
<li><img src="./images/logo_img_1.png" alt=""></li>
<li><img src="./images/logo_img_2.png" alt=""></li>
<li><img src="./images/logo_img_3.png" alt=""></li>
<li><img src="./images/logo_img_4.png" alt=""></li>
<li><img src="./images/logo_img_5.png" alt=""></li>
</ul>
</div>
<script>
var ul = document.querySelectorAll('ul')[0];
ul.innerHTML += ul.innerHTML; // 先复制一份需要移动的元素
var l = 0; //控制css的left值
var timer;
run(); // 一上来就要开始滚动
function run() {
clearInterval(timer); // 防止定时器的叠加
timer = setInterval(function () {
l -= 4;
ul.style.left = l + 'px';
if (l <= -1200) {
l = 0;
}
}, 10);
};
// 鼠标移入停止
var div = document.querySelector('div');
div.onmousemove = function () {
clearInterval(timer);
};
// 输入移出继续
div.onmouseleave = function () {
run();
};
</script>
</body>
</html>
跑马灯轮播图特效
左按钮:先瞬间定位到假图上,再过渡到正常图上
右按钮:先过渡到假图上,再瞬间定位到正常图上
left 值永远都是负的,只有负值,才能将图片向左拉
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
* {
margin: 0;
padding: 0;
list-style: none;
text-decoration: none;
}
div {
width: 400px;
height: 221px;
margin: 0 auto;
position: relative;
overflow: hidden;
}
div ul {
width: 2500px;
position: absolute;
left: 0;
transition: left 1s 0s ease;
}
div ul li {
float: left;
}
div ul li img {
width: 400px;
vertical-align: top;
}
div a {
position: absolute;
width: 40px;
height: 40px;
background-color: rgba(0, 0, 0, .2);
top: 50%;
margin-top: -20px;
text-align: center;
font-size: 30px;
line-height: 40px;
border-radius: 50%;
}
div a:hover {
background-color: rgba(0, 0, 0, .4);
}
div .leftBtn {
left: 0;
}
div .rightBtn {
right: 0;
}
</style>
</head>
<body>
<div>
<ul>
<li><img src="./images/0.jpg" alt=""></li>
<li><img src="./images/1.jpg" alt=""></li>
<li><img src="./images/2.jpg" alt=""></li>
<li><img src="./images/3.jpg" alt=""></li>
<li><img src="./images/4.jpg" alt=""></li>
</ul>
<a class="leftBtn" href="javascript:;"><</a>
<a class="rightBtn" href="javascript:;">></a>
</div>
<script>
var rightBtn = document.querySelector('.rightBtn');
var ul = document.querySelector('ul');
var cloneImg = ul.firstElementChild.cloneNode(true); // 先克隆第一张图片
ul.appendChild(cloneImg);
var idx = 0; // 表示当前图片的位置, 表示显示到第几张图,从0开始!
var lock = true; // 函数节流
rightBtn.onclick = function () {
if (!lock) return;
idx++;
ul.style.transition = 'left 1s 0s ease'; // 把失去的过渡,再次添加上
if (idx > 4) {
setTimeout(function () {
idx = 0;
ul.style.transition = 'none';
ul.style.left = 0;
}, 1000);
}
ul.style.left = -idx * 400 + 'px';
lock = false;
setTimeout(function () {
lock = true;
}, 1000);
};
var leftBtn = document.querySelector('.leftBtn');
lock = true;
leftBtn.onclick = function () {
if (!lock) return;
idx--;
if (idx < 0) {
idx = 5; // 最后一张图片上(复制的假图上)
ul.style.left = -idx * 400 + 'px';
ul.style.transition = 'none';
setTimeout(function () {
ul.style.transition = 'left 1s 0s ease';
idx = 4;
ul.style.left = -idx * 400 + 'px';
}, 0);
} else {
ul.style.left = -idx * 400 + 'px';
}
lock = false;
setTimeout(function () {
lock = true;
}, 1000);
};
</script>
</body>
</html>
呼吸轮播图特效
首先这样排好,不需要向右浮动了,也不用复制假图了
然后开启绝对定位,都合在一起。将其他图片都设置为透明,只有第一张不透明 opacity:1;
demo:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
* {
padding: 0;
margin: 0;
list-style: none;
text-decoration: none;
}
div {
width: 500px;
height: 276px;
margin: 20px auto;
position: relative;
}
div ul li {
position: absolute;
opacity: 0;
transition: opacity 1s 0s ease;
}
div ul li:first-child {
opacity: 1;
}
div ul li img {
width: 500px;
vertical-align: top;
}
div a {
position: absolute;
width: 40px;
height: 40px;
background-color: rgba(0, 0, 0, .2);
top: 50%;
margin-top: -20px;
text-align: center;
font-size: 30px;
line-height: 40px;
border-radius: 50%;
}
div a:hover {
background-color: rgba(0, 0, 0, .4);
}
div .leftBtn {
left: 0;
}
div .rightBtn {
right: 0;
}
</style>
</head>
<body>
<div>
<ul>
<li><img src="./images/0.jpg" alt=""></li>
<li><img src="./images/1.jpg" alt=""></li>
<li><img src="./images/2.jpg" alt=""></li>
<li><img src="./images/3.jpg" alt=""></li>
<li><img src="./images/4.jpg" alt=""></li>
</ul>
<a class="leftBtn" href="javascript:;"><</a>
<a class="rightBtn" href="javascript:;">></a>
</div>
<script>
var rightBtn = document.querySelector('.rightBtn');
var allLi = document.querySelectorAll('li');
var lock = true; // 函数节流
var idx = 0; // 表示当前图片的位置
rightBtn.onclick = function () {
if (!lock) return;
allLi[idx].style.opacity = '0'; // 当前图片变为透明
idx++;
if (idx > 4) {
idx = 0;
}
allLi[idx].style.opacity = '1'; // 下一张图片,由透明变为不透明
lock = false;
setTimeout(function () {
lock = true;
}, 1000);
};
var leftBtn = document.querySelector('.leftBtn');
lock = true;
leftBtn.onclick = function () {
if (!lock) return;
allLi[idx].style.opacity = '0';
idx--;
if (idx < 0) {
idx = 4;
}
allLi[idx].style.opacity = '1';
lock = false;
setTimeout(function () {
lock = true;
}, 1000);
};
</script>
</body>
</html>