烟花完整版
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> <style> #container{ width: 80%; height: 600px; border: 2px solid red; background: #000; margin:20px auto; cursor: pointer; position: relative; left: 0; top: 0; overflow: hidden; } .fire{ width: 10px; height:10px; position: absolute; bottom: 0; } .small-fire{ width: 10px; height:10px; position: absolute; border-radius: 50%; } </style> <script src="../public.js"></script> </head> <body> <div id="container"></div> </body> <script> // for(){ // ali[i] = i // ali[i].onclick = function(){ // this // } // } // 范围随机数 function Fire(options) { this.x=options.x; this.y=options.y; this.cont=options.parent; this.arr=[]; this.init(); } Fire.prototype.init = function(){ // 主体烟花,设置样式,位置 this.ele = document.createElement("div"); this.ele.className = "fire"; this.ele.style.left = this.x + "px"; this.ele.style.background = randomColor(); this.cont.appendChild(this.ele) // 2.开始运动,运动结束 this.animate() } Fire.prototype.animate=function () { move(this.ele,{top:this.y},function () { this.ele.remove() this.createSmall() }.bind(this))//强行把原型的this穿进去,因为这里本来的this是function前面的。 }; Fire.prototype.createSmall = function(){ // 创建小烟花,运动,删掉 var r = Math.round(Math.random()*100+150); var num = random(50,60); console.log(num) for(var i=0;i<num;i++){ var div = document.createElement("div");//用var无法消失小烟花 div.className = "small-fire"; div.style.background = randomColor(); div.style.left = this.x + "px"; div.style.top = this.y + "px"; div.setAttribute("i",i); this.cont.appendChild(div); // this.arr.push(div) // 产生随机坐标 var l=Math.round(Math.sin(Math.PI/180*10*i)*r) + this.x;//必须要取整,否则来回抖动,永远无法到达目的地也就无法消失。 var t=Math.round(Math.cos(Math.PI/180*10*i)*r) + this.y; // 在move的回调函数中,找不到每个div: // 原因:异步:for循环立即执行,回到函数等待执行,回调函数执行时,循环已经结束多时,div已经被重复覆盖 // 解决方案: // 2.使用bind将div强行传进去 // 3.使用匿名函数生成新的作用域,保存div:*** // 4.利用let触发块级作用域,保存div:√,即for每次循环,那个div都是个新的div, // 后面就可以直接用了 //========================================================================= // ;(function (div) { // move(div,{ // left:l, // top:t // },function(){ // div.remove() // }) // })(div);//匿名函数的方法,匿名函数自动执行,for没执行一次,匿名函数也执行一次,进行传参。div可以用var声明 // ============================================================================= // move(div,{ // left:l, // top:t // },function(){ // div.remove() // }) //let块级作用于办法,利用let触发块级作用域,保存div:√,即for每次循环,那个div都是个新的div,后面就可以直接用了,div用let声明,后面什么不用改。 //============================================================================= // // move(div,{ // left:l, // top:t // },()=>{ // for(var i=0;i<this.arr.length;i++){ // this.arr[i].remove() // } // });//提前定义数组保存,结束时根据数组删除,记得如果使用this,用箭头函数。否则用that传;div可以用var声明 //=============================================================================== move(div,{ left:l, top:t },function(){ this.remove() }.bind(div))//// 2.使用bind将div强行传进去,记得里面使用this,代表的是传进来的div //====================================================================================== } } //======================================================================== var ocont=document.getElementById("container"); ocont.onclick=function (eve) { var e=eve||window.event; new Fire({ x:e.offsetX, y:e.offsetY, parent:this }); } </script> </html>
长风破浪会有时,直挂云帆济沧海