<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title></title> <link rel="stylesheet" type="text/css" href="main.css"> </head> <body> <div class="section"> <h2 class="tit">限时抢购</h2> <div class="wrap"> <div class="wrap_bar"> <div class="bar"> <div class="inputs"> <input type="text" /> <input type="button" value="确定" /> </div> <p class = "showTimer">剩余00天00时00分00秒</p> <div class="content"> <a href="#"><img src="img/pic.jpg" /></a> <h3>商品标题商品标题商品标题商品标题</h3> <span>抢购价:</span> <a class="prise">¥<span>145</span></a> </div> </div> </div> <div class="wrap_bar"> <div class="bar"> <div class="inputs"> <input type="text" /> <input type="button" value="确定" /> </div> <p class = "showTimer">剩余00天00时00分00秒</p> <div class="content"> <a href="#"><img src="img/pic.jpg" /></a> <h3>商品标题商品标题商品标题商品标题</h3> <span>抢购价:</span> <a class="prise">¥<span>145</span></a> </div> </div> </div> <div class="wrap_bar"> <div class="bar"> <div class="inputs"> <input type="text" /> <input type="button" value="确定" /> </div> <p class = "showTimer">剩余00天00时00分00秒</p> <div class="content"> <a href="#"><img src="img/pic.jpg" /></a> <h3>商品标题商品标题商品标题商品标题</h3> <span>抢购价:</span> <a class="prise">¥<span>145</span></a> </div> </div> </div> <div class="wrap_bar la"> <div class="bar"> <div class="inputs"> <input type="text" /> <input type="button" value="确定" /> </div> <p class = "showTimer">剩余00天00时00分00秒</p> <div class="content"> <a href="#"><img src="img/pic.jpg" /></a> <h3>商品标题商品标题商品标题商品标题</h3> <span>抢购价:</span> <a class="prise">¥<span>145</span></a> </div> </div> </div> </div> <div class="cart"> <div class="sellTit"> <span>商品名称</span> <span>价钱</span> </div> <div id="sellItem"> <!-- 由js生成倒计时完成的商品条目 --> </div> <p>总价:<span id="sumPrise">0</span>元</p> </div> </div> </div> <script src="doMove.js"></script> <script src="getId.js"></script> <!-- <script src="shake.js"></script> --> <script src="main.js"></script> </body> </html>
$(function(){ var oBar = $class('div','bar'); //主要被操作的div var oContent = $class('div','content'); //商品条目父级div var oInputDiv = $class('div','inputs'); //输入框按钮的父级div var oP = $class('p','showTimer'); //显示倒计时的p标签 var oPrise = $('sumPrise'); //商品总价标签 //引子 点击调用倒计时函数 for(var i=0,len=oInputDiv.length; i<len; i++){ //同步事件可以在外面获取按钮 var oBtn = oInputDiv[i].getElementsByTagName('input')[1]; oBtn.index = i; oBtn.onclick = function(){ //异步事件只能点击了再获取 //获取输入框的内容 //传入setTime倒计时函数 var oInput = oInputDiv[this.index].getElementsByTagName('input')[0].value; setTime(oInput,this.index); } } //'August 10,2018 1:54:50' //倒计时函数 回调抖动函数 ---> 抖动回调下滑透明度函数 ----> 透明度回调增加商品条目函数 function setTime(Dates,index){ // 终点时间只用获取一次 // nP为对应的倒计时p标签 var endDate = new Date(Dates); var nP = oP[index]; //避免定时器重叠,主要清除timer2 clearTimeout(nP.timer); clearTimeout(nP.timer2); nP.timer = setTimeout(function timeCnt(){ //****t:相差秒数; 以及后面的相关计算,每次都要计算一次 var newDate = new Date(); var t = Math.floor( (endDate-newDate)/1000 ); var mDay = Math.floor( t/86400 ); var mHour = Math.floor( t%86400/3600 ); var mMin = Math.floor( t%86400%3600/60 ); var mSec = t%60; //// //赋值 var str = '剩余'+mDay+'天'+mHour+'时'+mMin+'分'+mSec+'秒' nP.innerHTML = str; //重复执行 nP.timer2 = setTimeout(timeCnt,1000); //****t == 0表示倒计时结束 if( t == 0 ){ clearTimeout(nP.timer2); //****bar抖动完成回调 【下滑】 和 【透明度】 变化两个函数,透明度回调 【添加条目函数】 shake( oBar[index],'left',function(){ doMove( oBar[index],'top',5,130,0,30 ); tOpacity(oBar[index],-0.05,function(){ addItem(index); }); }); } ////if结束 },0); } //抖动函数 function shake( obj,attr,endFn ){ //****抖动参数 var arr = []; for(var i=10; i>0; i-=1 ){ arr.push( i,-i ); } arr.push(0); //// // // obj.onOff = true; var i=0; var oAttr = parseInt( getStyle(obj,attr) ); clearInterval(obj.timer); obj.timer = setInterval(function(){ //*****基本的改值赋值操作 oAttr += arr[i]; i++; obj.style[attr] = oAttr + 'px'; //***** //如果左右抖动停止就执行回调函数 if( arr[i] == 0 ){ (endFn) && (endFn()); } //***** },30); } //透明度函数 function tOpacity(obj,attr,endFn){ //attr字符串转数字类型 attr = parseFloat(attr); var arug = null; setTimeout(function timer(){ //****取当前值,改变当前值,赋值 arug = parseFloat( getStyle(obj,'opacity') ); arug += attr; obj.style.opacity = arug; //// //透明度为0停止变化执行回调 if( arug != 0 ){ setTimeout(timer,30); }else{ obj.style.display = 'none'; endFn(); } },30); } //增加商品条目函数 ----> 回调计算价格函数 function addItem(index){ //找到商品条目父级标签 var oParent = $('sellItem'); //****创建出单个item包含的节点 var eDiv = document.createElement('div'); var eH3 = document.createElement('h3'); var eSpan = document.createElement('span'); var eImg = document.createElement('img'); //// //****找到当前bar的商品数据,标题,价格,图片 var eH3txt = oContent[index].getElementsByTagName('h3')[0].innerHTML; var eSpantxt = oContent[index].getElementsByTagName('a')[1].getElementsByTagName('span')[0].innerHTML; var eImgtxt = oContent[index].getElementsByTagName('img')[0].src; //// //****设置item标签的class属性,给标题赋值,价格赋值,图片地址赋值 eDiv.setAttribute('class','item'); eH3.innerHTML = eH3txt; eSpan.innerHTML = '¥'+ eSpantxt; eImg.setAttribute('src',eImgtxt); //// //****按顺序追加到item里 eDiv.append(eH3); eDiv.append(eSpan); eDiv.append(eImg); oParent.append(eDiv); //// //价格计算回调,传入bar获取到的数据 counter(eSpantxt); } //计算价格函数 function counter(prise){ //转成number类型 prise = parseFloat(prise); //现有价格转成number类型 var oNum = parseFloat(oPrise.innerHTML); //计算赋值 oNum += prise; oPrise.innerHTML = oNum; } });
需求:
需求分析:【倒计时】 --> 【对应条目抖动】 --> 【抖动完后下滑并透明】 --> 【完全透明后增加一个条目】 --> 【增加条目后计算总价】
实现思路:
倒计时部分课上有讲,主要是怎样点击按钮后获得输入框的内容会方便点,在HTML里我把输入框和按钮放在一个div里,这样就可以用getElementsByTagName()[]下标来获取,获取到的值传入倒计时函数,倒计时函数经过一些处理后,每秒计算的值放入到显示的p标签,这里要保证p标签的顺序是和输入框按钮的顺序是一样的,因为这里也是通过下标来找。
然后就是倒计时结束后清除定时器,回调抖动函数,抖动结束后回调下滑和透明度变化函数,透明度结束后回调增加商品条目函数,商品条目结束后回调计算总价函数,总共回调5次。
难点:回调太多,不可避免
难点解决方案:将回调函数独立成有名字的函数,通过传参来使用,避免缩进太多
解决不了的难点:回调好像是无法避免的,叫回调地狱,除了上一条的解决方案,还有ES6的promise来解决
涉及到的新知识:ES6的promise解决回调地狱
备注:回调嵌套容易出问题,如果某层修改了一点会整条链子卡在那里,而且deBug不好做
找段时间做一个向某个方向渐移渐隐的函数