封装运动函数,来实现烟花的向上移动
注意:
首先在运动函数中:
1、在每一次执行新的函数时,一定要清除上一次的定时器,否则会造成定时器的累加
2、注意浏览器的兼容问题
3、要判断步进值的正负
1 var timer = null;//定时器 2 function startMove(obj, objArr, callback) { 3 clearInterval(obj.timer);//清除上一次的定时器 4 var onOff = false;//定义开关,初始值为false 5 obj.timer = setInterval(function () { 6 // console.log(attr);//属性 7 // console.log(objArr[attr]);//属性值 8 //遍历对象 9 for (var attr in objArr) { 10 //获取实时位置 11 var tmpPos = parseInt(getPos(obj, attr)); 12 //定义步长值 13 var speed = (objArr[attr] - tmpPos) / 10; 14 //判断步长值 15 speed = speed > 0 ? Math.ceil(speed) : Math.floor(speed); 16 17 //赋值给对象 18 obj.style[attr] = tmpPos + speed + 'px'; 19 20 } 21 //判断元素运动的临界值 22 if((tmpPos + speed)==objArr[attr]) onOff = true; 23 if(onOff){ 24 clearInterval(obj.timer); 25 if(callback){ 26 callback(); 27 } 28 } 29 }, 30) 30 31 } 32 //封装函数获取实时位置 33 function getPos(obj, attr) { 34 if (obj.currentStyle) { 35 return currentStyle[attr];//IE 36 } else { 37 return getComputedStyle(obj)[attr];//非IE 38 } 39 }
面向对象
其次:
在面向对象中
1、在绑定事件中,切记实例化对象
2、在调用运动函数时,记得参数以一一对应,并且在实现之后清除自身
3、在小烟花中,在后面调用运动函数时,要使用块级作用域,将sFire保存起来
一次执行完毕,执行下一次
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <meta name="viewport" content="width=device-width, initial-scale=1.0"> 6 <meta http-equiv="X-UA-Compatible" content="ie=edge"> 7 <title>Document</title> 8 <style> 9 * { 10 margin: 0; 11 padding: 0; 12 } 13 14 #cont { 15 1200px; 16 height: 600px; 17 background: black; 18 margin: 50px auto; 19 position: relative; 20 cursor:pointer; 21 background:black; 22 /* 要设置相对定位,否则大烟花无法与鼠标位置相对应 */ 23 } 24 25 .big-fire { 26 background: red; 27 position: absolute; 28 /* 设置bottom时,top获取为最大值,减去鼠标点击位置 */ 29 bottom: 0px; 30 6px; 31 height: 6px; 32 } 33 34 .small-fire { 35 10px; 36 height: 10px; 37 position: absolute; 38 border-radius: 50%; 39 } 40 </style> 41 </head> 42 <body> 43 <div id="cont"></div> 44 <script src="./move.js"></script> 45 <script> 46 //1 获取节点 47 var contObj = document.getElementById('cont'); 48 //2 绑定事件获取鼠标实时位置 49 contObj.onclick = function(eve){ 50 var e = eve || window.event; 51 var mousePos={ 52 x:e.offsetX, 53 y:e.offsetY 54 } 55 // console.log(e.offsetX); 56 // console.log(e.offsetY); 57 new Fire(contObj,mousePos); 58 } 59 60 //3 封装烟花构造函数 61 function Fire(contObj,mousePos){ 62 //!!! 63 this.contObj = contObj; 64 this.mousePos = mousePos; 65 //创建大烟花,设置class,left,bg 66 var bigFire = document.createElement('div'); 67 bigFire.className = 'big-fire'; 68 bigFire.style.left = mousePos.x + 'px'; 69 bigFire.style.backgroundColor = this.ranColor(); 70 contObj.appendChild(bigFire); 71 var that = this; 72 startMove(bigFire,{top:mousePos.y},function(){ 73 bigFire.remove(); 74 that.smallFire(); 75 }) 76 } 77 /*封装小烟花*/ 78 Fire.prototype.smallFire = function(){ 79 var fireNum = 20; 80 for(var i = 0;i<fireNum;i++){ 81 var sFire = document.createElement('div'); 82 sFire.className = 'small-fire'; 83 contObj.appendChild(sFire); 84 sFire.style.backgroundColor = this.ranColor(); 85 //小烟花初始位置 86 sFire.style.left = this.mousePos.x + 'px'; 87 sFire.style.top = this.mousePos.y + 'px'; 88 //小烟花终点位置 89 var sLeft =this.ranNum(0,contObj.offsetWidth - sFire.offsetWidth); 90 var sTop =this.ranNum(0,contObj.offsetHeight - sFire.offsetHeight); 91 //6 调用运动函数 92 //因为for的循环速度,比烟花运动到终点的速度快 93 // 调用使用运动函数是的sFire,在烟花到了终点位置时,已经被其他新的烟花给覆盖了 94 // 使用块级作用域,将sFire保存起来,一次执行完毕,执行下一次 95 (function(sFire){ 96 startMove(sFire,{left:sLeft,top:sTop},function(){ 97 sFire.remove(); 98 }); 99 })(sFire)//!!!注意调用小烟花 100 } 101 } 102 //随机颜色 103 Fire.prototype.ranColor=function(){ 104 var r = this.ranNum(0,255); 105 var g = this.ranNum(0,255); 106 var b = this.ranNum(0,255); 107 return `rgb(${r},${g},${b})`; 108 } 109 //封装随机数 110 Fire.prototype.ranNum=function(min,max){ 111 return Math.round(Math.random()*(max-min)+min); 112 } 113 </script> 114 </body> 115 </html>