本文介绍如何利用JavaScript实现活动页面的秒杀商品排序逻辑。通过获取当前小时数,计算时间差,动态调整数组顺序,使当前正在进行的秒杀活动排在首位,历史活动移至末尾。该算法可应用于电商秒杀场景,实现基于时间的动态列表展示效果,提升用户体验。
秒杀排序算法背景与需求
制作一个活动页面,特别是秒杀列表页,需要用到一种基于时间的排序算法。起初我自行思考了多种方案,但未能成功实现。随后,我向一位后端PHP同事请教,他提供了一段算法代码。初看之下,这似乎只是一个纯后端逻辑,难以直接转化为前端DOM效果。但经过反复研读,我发现其逻辑可以映射到页面展示上,于是对其进行了修改和完善,最终实现了预期效果,现分享于此。
页面的具体需求如下:活动时间段从11点持续到20点,每隔一小时进行一场秒杀。系统需判断当前时间,若某场秒杀正在进行,则其商品列表显示为“正在秒杀”状态;而在此之前的历史秒杀商品,则需按规则移至列表末尾,依次类推,确保当前及未来的活动始终优先展示。
以时间顺序为例,初始状态下(11点前),顺序为:11, 12, 13, 14, 15, 16, 17, 18, 19, 20(点)。当时间推进至12点时,顺序变为:12, 13, 14, 15, 16, 17, 18, 19, 20, 11(点)。当时间推进至13点时,顺序调整为:13, 14, 15, 16, 17, 18, 19, 20, 12, 11(点)。依此类推,直至最后时刻,顺序变为:20, 19, 18, 17, 16, 15, 13, 12, 11(点)。
核心算法实现与调用
以下是后端同事提供的原始纯算法代码。
function show_test(hour)
{
p = ['13 dian','14 dian','15 dian ','16 dian','17 dian','18 dian','19 dian','20 dian'];
console.log('原顺序是');
console.log(p);
date = new Date();
curHour = date.getHours();
pos = curHour - 13;
//pos = hour;
s = '活动'+ p[pos]+"正在进行";
console.log(s);
desc = '当前的顺序应该是';
p.reverse();
console.log(pos);
tmp = []
for(i = 0 ; i<pos; i++){
tmp.push(p.pop());
}
p.reverse();
p = p.concat(tmp.reverse());
console.log(desc);
console.log(p);
console.log("\n\n");
}
调用该算法的方式如下。
var curHour=new Date().getHours();
show_test(curHour);
算法前端页面转化
该算法在逻辑上完美契合了上述需求描述。然而,如何将这一逻辑真正转化为前端页面的可视化展示,成为了新的挑战。经过深入思考与调试,我成功将其落地实现。
//首先定义一个包含了每个秒杀的商品的id和图片的数组 img1是商品图片 img2是秒杀时间 img3是商品描述
var data=[
{ id:1,
time:11,
img1:"1.jpg",
img2:"11.jpg",
img3:"111.jpg"
},
{ id:2,
time:12,
img1:"2.jpg",
img2:"22.jpg",
img3:"222.jpg"
},
{ id:3,
time:13,
img1:"3.jpg",
img2:"33.jpg",
img3:"333.jpg"
},
{ id:4,
time:14,
img1:"4.jpg",
img2:"44.jpg",
img3:"444.jpg"
},
{ id:5,
time:15,
img1:"5.jpg",
img2:"55.jpg",
img3:"555.jpg"
},
{ id:6,
time:16,
img1:"6.jpg",
img2:"66.jpg",
img3:"666.jpg"
},
{ id:7,
time:17,
img1:"7.jpg",
img2:"77.jpg",
img3:"777.jpg"
},
{ id:8,
time:18,
img1:"8.jpg",
img2:"88.jpg",
img3:"888.jpg"
},
{ id:9,
time:19,
img1:"9.jpg",
img2:"99.jpg",
img3:"999.jpg"
},
{ id:10,
time:20,
img1:"10.jpg",
img2:"101.jpg",
img3:"1010.jpg"
}
];
//对象数组排序
function compare(propertyName) {
return function (object1, object2) {
var value1 = object1[propertyName];
var value2 = object2[propertyName];
if (value2 < value1) {
return -1;
}else if (value2 > value1) {
return 1;
}else {
return 0;
}
}
}
//因为现在的数组已经变成了一个复杂的数组 所以排序要用到根据对象的某个属性排序这歌方法
//这个方法在javascript高级程序设计里面有提到过
function itemShow(hour)
{
p=data;
//当前时间
curHour = hour;
//对应时间的数组下标
pos = curHour - 11;
if(pos<=0){ //如果没到11点就显示最开始的顺序
pos=0;
}else if(pos>=9){//如果超过20点 就完全倒序
pos=9
}
s = '活动'+ p[pos]+"正在进行";
console.log(s);
//根据数组里的 时间这个属性反向排序
p.reverse(compare("time"));
console.log(pos);
console.log(p);
//定义一个临时数组存放过时的商品项
tmp = []
for(i = 0 ; i<pos; i++){
tmp.push(p.pop());
}
//将剩余的再反相排序
p.reverse(compare("time"));
//将未到秒杀时间的商品项目与已经过期的数组链接
p = p.concat(tmp.reverse(compare("time"))); //
console.log(desc);
console.log(p);
for(var i=0;i<data.length;i++){
if(i==0){//正在秒杀
$(".item").eq(0).append("<img src='"+p[i].img1+"' id="+p[i].id+">")
$(".item").eq(0).append("<img src='"+"killsecond_now.jpg"+"'>")
$(".item").eq(0).append("<img src='"+p[i].img3+"'>")
}else{
$(".item").eq(i).append("<img src='"+p[i].img1+"' id="+p[i].id+">")
$(".item").eq(i).append("<img src='"+p[i].img2+"'>")
$(".item").eq(i).append("<img src='"+p[i].img3+"'>")
}
}
}
至此,算法已成功转化为页面展示效果。希望这段关于JavaScript时间排序算法的分享,能为大家提供有益的参考与启发。