<!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不好做
找段时间做一个向某个方向渐移渐隐的函数
转载于: