DOM高级
我们在实际开发中,页面中有很多需要用到动画的效果,如果每一个效果都需要我们手动创建定时器来写的话,的,代码会冗余,逻辑也会变得很复杂,所以我们需要手动封装一个专门用于执行动画的函数。
以一个div点击后执行动画为例来封装。
一、简单的运动
html布局s
1 2 3 4 5 6 7 8 9 10 11
| <style> .box{ width: 100px; height: 100px; background-color: pink; position:absolute; left: 0; top: 0; } </style> <div class="box"></div>
|
js代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| var box = document.querySelector(".box");
box.onclick=function(){ var currentStyle = window.getComputedStyle(box)["left"]; currentStyle = parseInt(currentStyle); var timer = setInterval(function(){ currentStyle += 5; if(currentStyle >= 200){ currentStyle = 200; clearInterval(timer); } box.style.left = currentStyle + 'px'; },20); }
|
二、简单封装
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| var box = document.querySelector(".box");
box.onclick=function(){ animate(box,"left",200) }
function animate(ele,attr,target){ var currentStyle = window.getComputedStyle(ele)[attr]; currentStyle = parseInt(currentStyle); var timer = setInterval(function(){ currentStyle += 5; if(currentStyle >= target){ clearInterval(timer); } ele.style.left = currentStyle + 'px'; },20); }
|
三、多属性动画
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| var box = document.querySelector(".box");
box.onclick=function(){ animate(box,{"left":200,"top":300}) }
function animate(ele,obj){ for(let attr in obj){ let target = obj[attr]; var currentStyle = window.getComputedStyle(ele)[attr]; currentStyle = parseInt(currentStyle); let timer = setInterval(function(){ console.log(123); currentStyle += 5; if(currentStyle >= target){ clearInterval(timer); } ele.style[attr] = currentStyle + 'px'; },20); } }
|
四、动画不均匀的处理
速度的不成比例所以造成运动不均与,所以速度应该用比例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
| var box = document.querySelector(".box");
box.onclick=function(){ animate(box,{"left":200,"top":300}) }
function animate(ele,obj){ for(let attr in obj){ let target = obj[attr]; let currentStyle = window.getComputedStyle(ele)[attr]; currentStyle = parseInt(currentStyle); let timer = setInterval(function(){ var percent = (target - currentStyle)/10; if(percent>0){ percent = Math.ceil(percent); }else{ percent = Math.floor(percent); } currentStyle += percent; if(currentStyle == target){ clearInterval(timer); } ele.style[attr] = currentStyle + 'px'; },20); } }
|
五、透明度的处理
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
| var box = document.querySelector(".box");
box.onclick=function(){ animate(box,{"left":0,"top":300,"opacity":50}) }
function animate(ele,obj){ for(let attr in obj){ let target = obj[attr]; let currentStyle = window.getComputedStyle(ele)[attr]; if(attr == 'opacity'){ currentStyle = parseFloat(currentStyle)*100; }else{ currentStyle = parseInt(currentStyle); } let timer = setInterval(function(){ let percent = (target - currentStyle)/10; if(percent>0){ percent = Math.ceil(percent); }else{ percent = Math.floor(percent); } currentStyle += percent; if(currentStyle == target){ clearInterval(timer); } if(attr == 'opacity'){ ele.style[attr] = currentStyle/100; }else{ ele.style[attr] = currentStyle + 'px'; } },20); } }
|
效果没问题之后,再将透明度扩大的100倍缩小回来:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52
| var box = document.querySelector(".box");
box.onclick=function(){ sport(box,{"left":0,"top":300,"opacity":0.5}) }
function sport(ele,obj){ for(let attr in obj){ let target = obj[attr]; let currentStyle = window.getComputedStyle(ele)[attr]; if(attr == 'opacity'){ currentStyle = parseFloat(currentStyle)*100; target = target * 100; }else{ currentStyle = parseInt(currentStyle); } let timer = setInterval(function(){ let percent = (target - currentStyle)/10; if(percent>0){ percent = Math.ceil(percent); }else{ percent = Math.floor(percent); } currentStyle += percent; if(currentStyle == target){ clearInterval(timer); } if(attr == 'opacity'){ ele.style[attr] = currentStyle/100; }else{ ele.style[attr] = currentStyle + 'px'; } },20); } }
|
六、动画结束的处理
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68
| box.onclick=function(){ sport(box,{"left":0,"top":300,"opacity":0.5},function(){ box.style.background = 'red'; }) }
function sport(ele,obj,cb){ let timerObj = {}; for(let attr in obj){ let target = obj[attr]; let currentStyle = window.getComputedStyle(ele)[attr]; if(attr == 'opacity'){ currentStyle = parseFloat(currentStyle)*100; target = target * 100; }else{ currentStyle = parseInt(currentStyle); } timerObj[attr] = setInterval(function(){ let percent = (target - currentStyle)/10; if(percent>0){ percent = Math.ceil(percent); }else{ percent = Math.floor(percent); } currentStyle += percent; if(currentStyle == target){ clearInterval(timerObj[attr]); delete timerObj[attr]; let k=0; for(let i in timerObj){ k++; } if(k==0){ console.log("运动结束了"); cb(); } } if(attr == 'opacity'){ ele.style[attr] = currentStyle/100; }else{ ele.style[attr] = currentStyle + 'px'; } },20); } }
|
七、滑动轮播图
html布局
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| <div class="banner"> <ul class="imgBox clearfix"> <li>1</li> <li>2</li> <li>3</li> <li>4</li> <li>5</li> </ul> <ol class="point"> </ol> <div class="leftRightTab"> <a href="javascript:;" class="left"><</a> <a href="javascript:;" class="right">></a> </div> </div>
|
css样式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82
| *{ padding: 0; margin: 0; } ul,ol{ list-style-type: none; } a{ text-decoration:none; } .clearfix:after{ content:""; display:block; clear:both; } .banner{ width: 600px; height: 400px; border:2px solid #000; margin:auto; position:relative; overflow:hidden; } .banner ul{ height: 100%; background-color: pink; position:absolute; left:0; top: 0; } .banner ul li{ width: 600px; height: 100%; float:left; display:flex; justify-content: center; align-items:center; color:#fff; font-size:100px; } .banner ol{ height: 20px; background-color: #999; opacity:0.5; border-radius:10px; position:absolute; bottom:40px; left:50%; transform:translateX(-50%); display: flex; justify-content: space-evenly; align-items: center; } .banner ol li{ width: 10px; height: 10px; border-radius: 50%; background-color: #fff; } .banner ol li.active{ background-color: #06a; } .banner div{ width: 100%; height: 40px; position: absolute; left: 0; top: 50%; transform: translateY(-50%); display: flex; justify-content: space-between; align-items: center; } .banner div a{ width: 20px; height: 40px; background-color: rgba(0,0,0,.4); color: #fff; display: flex; justify-content: center; align-items: center; }
|
js代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160
| var banner = document.querySelector(".banner"); var imgBox = banner.querySelector("ul"); var pointBox = banner.querySelector("ol"); var btnBox = banner.querySelector(".leftRightTab"); var imgBoxLength = imgBox.children.length; var imgWidth = imgBox.children[0].offsetWidth; var onOff = true;
setPoint(); function setPoint(){ var pointNum = imgBox.children.length; pointBox.style.width = pointNum*20+'px'; for(var i=0;i<pointNum;i++){ var li = document.createElement("li"); li.setAttribute("index",i+1); if(i==0){ li.className='active'; } pointBox.appendChild(li); } }
var index = 1; handleUl(); function handleUl(){ var firstImgLi = imgBox.children[0].cloneNode(true); var lastImgLi = imgBox.children[imgBoxLength-1].cloneNode(true); imgBox.insertBefore(lastImgLi,imgBox.children[0]); imgBox.appendChild(firstImgLi); imgBox.style.width = imgWidth * imgBox.children.length + 'px'; imgBox.style.left = -imgWidth*index + 'px'; }
autoLoop(); var timerId; function autoLoop(){ timerId = setInterval(function(){ index++; handleMove(); },1000); }
function handleMove(){ animate(imgBox,{left:-index*imgWidth},function(){ if(index == imgBox.children.length-1){ index=1; imgBox.style.left = -index*imgWidth + 'px'; } if(index==0){ index = imgBoxLength; imgBox.style.left = -index*imgWidth + 'px'; } for(var i=0;i<pointBox.children.length;i++){ pointBox.children[i].className = ''; } pointBox.children[index-1].className = 'active'; onOff = true; }); }
banner.onmouseover=function(){ clearInterval(timerId); } banner.onmouseout=function(){ autoLoop(); }
btnBox.onclick=function(e){ if(!onOff){ return } onOff = false; var e = e || window.event; var target = e.target || e.srcElement; if(target.className=='left'){ index--; } if(target.className=='right'){ index++; } handleMove(); }
pointBox.onclick=function(e){ if(!onOff){ return false; } var e = e || window.event; var target = e.target || e.srcElement; if(target.nodeName == 'LI'){ onOff = false; index=target.getAttribute("index"); handleMove(); } }
function animate(ele,obj,cb){ let timerObj = {}; for(let attr in obj){ let target = obj[attr]; let currentStyle = window.getComputedStyle(ele)[attr]; if(attr == 'opacity'){ currentStyle = parseFloat(currentStyle)*100; target = target * 100; }else{ currentStyle = parseInt(currentStyle); } timerObj[attr] = setInterval(function(){ let percent = (target - currentStyle)/10; if(percent>0){ percent = Math.ceil(percent); }else{ percent = Math.floor(percent); } currentStyle += percent; if(currentStyle == target){ clearInterval(timerObj[attr]); delete timerObj[attr]; let k=0; for(let i in timerObj){ k++; } if(k==0){ console.log("运动结束了"); cb(); } } if(attr == 'opacity'){ ele.style[attr] = currentStyle/100; }else{ ele.style[attr] = currentStyle + 'px'; } },20); } }
|
测试发现无法实现秒切,修改动画函数:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65
| function move(ele,obj,cb){ let timerObj = {}; for(let attr in obj){ let target = obj[attr]; let currentStyle = window.getComputedStyle(ele)[attr]; if(attr == 'opacity'){ currentStyle = parseFloat(currentStyle)*100; target = target * 100; }else{ currentStyle = parseInt(currentStyle); } timerObj[attr] = setInterval(function(){ let percent = (target - currentStyle)/10; if(percent>0){ percent = Math.ceil(percent); }else{ percent = Math.floor(percent); } currentStyle += percent; if(currentStyle == target){ clearInterval(timerObj[attr]); delete timerObj[attr]; let k=0; for(let i in timerObj){ k++; } if(attr == 'opacity'){ ele.style[attr] = currentStyle/100; }else{ ele.style[attr] = currentStyle + 'px'; } if(k==0){ console.log("运动结束了"); cb(); } }else{ if(attr == 'opacity'){ ele.style[attr] = currentStyle/100; }else{ ele.style[attr] = currentStyle + 'px'; } } },20); } }
|
最终效果:
最终的轮播效果 |
---|
 |
八、swiper的使用
官网:https://www.swiper.com.cn/
下载:https://www.swiper.com.cn/download/index.html#file1
看文档,复制代码
配置选项
自动轮播
1 2 3
| autoplay: { delay: 1000, },
|
轮播方向
1
| direction: 'horizontal',
|
是否循环
移入停止移出继续
1 2 3 4 5 6 7
| var container = document.querySelector('.swiper-container') container.onmouseenter = function(){ mySwiper.autoplay.stop(); } container.onmouseleave = function(){ mySwiper.autoplay.start(); }
|
查看API文档:https://www.swiper.com.cn/api/index.html