0715 NOTE
五星好评
功能分析:
1.星星点亮为红,不亮为白底黑框
2.五星评价后有打分,一颗星一分,初始为0
3.鼠标悬停在星星,目标对象及其前列星星全亮,移开则恢复默认
4.鼠标点击后样式修改,移开也不变,除非再次点击
5.星星上方对应点亮星数有不同表情显示,根据星星目标展示在当前星星上方
/*css*/
body{
font: 12px/150% tahoma,arial,Microsoft YaHei,Hiragino Sans GB,"\u5b8b\u4f53",sans-serif;
}
<script type="module">
import Star from "./js/Star.js";
var arr=["快递包装","送货速度","配送员服务"]
arr.forEach(item=>{
var star=new Star(item);
star.appendTo("body");
})
</script>
//Star.js
import Component from "./Component.js";
import Utils from "./Utils.js";
export default class Star extends Component{
itemCon;
statArr;
face;
score;
pos=-1;
constructor(label){
super();
this.elem.innerHTML=`
<label class='label'>${label}</label>
<div class='star-con'>
<div class='face'></div>
<div class='item-con'>
<div class='star-item'></div>
<div class='star-item'></div>
<div class='star-item'></div>
<div class='star-item'></div>
<div class='star-item'></div>
</div>
</div>
<span class='score'>0分</span>
`
this.elem.className="star"; //class名命名
Star.setCss(); //调用方法setCss
this.itemCon=this.elem.querySelector(".item-con"); //元素获取
this.score=this.elem.querySelector(".score"); //元素获取
this.face=this.elem.querySelector(".face"); //元素获取
this.statArr=Array.from(this.itemCon.children); //变量classCon的子元素列表获取并转化为数组
this.itemCon.addEventListener("mouseover",e=>this.mouseHandler(e)); //变量itemCon添加事件侦听,鼠标进入事件
this.itemCon.addEventListener("mouseleave",e=>this.mouseHandler(e)); //变量itemCon添加事件侦听,鼠标移出事件
this.itemCon.addEventListener("click",e=>this.clickHanler(e)); //变量itemCon添加事件侦听,点击事件
}
mouseHandler(e){
if(e.type==="mouseover"){ //鼠标进入
if(e.target.className!=="star-item") return; //如果目标对象class名不是star-item,返回 不执行
var index=this.statArr.indexOf(e.target); //查找statArr中对应当前目标对象的元素所在下标,赋给变量index
Object.assign(this.face.style,{ //变量face的样式设置
display:"block",
left:16*index+"px",
backgroundPositionX:-(5-index-1)*20+"px"
})
this.changeStar((i)=>{ //将箭头函数作为参数传入
return i<=index || i<=this.pos;
},index >= this.pos ? (index+1) : this.pos+1);
}else if(e.type==="mouseleave"){ //鼠标离开
this.face.style.display="none"; //变量face的样式设置
this.changeStar((i)=>{
return i<=this.pos
},this.pos<0 ? 0 : this.pos+1);
}
}
changeStar(requirement,score){
this.statArr.forEach((item,i)=>{ //i作为数组下标,调用requirement函数,返值
if(requirement(i)) item.style.backgroundPositionY="-16px"; //改变样式背景图,背景图为精灵图,实现了点亮星星的操作
else item.style.backgroundPositionY="0px";
})
this.score.textContent=score+"分";
this.score.style.color=score!==0 ? "red" : "#999";
}
clickHanler(e){
if(e.target.className!=="star-item") return;
this.pos=this.statArr.indexOf(e.target);
}
static setCss(){ //设置样式
if(super.setCss()) return;
Utils.setCss(`
.star{
position: relative;
width: 160px;
height: 46px;
float:left;
margin-right:60px;
}
.star>.label{
float: left;
height: 16px;
line-height: 16px;
margin-right: 10px;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
color: #666;
position: relative;
top:16px;
}
.star>.star-con
{
float: left;
position: relative;
}
.star>.star-con>.item-con{
position: absolute;
width: 80px;
top:16px;
}
.star>.star-con>.item-con>.star-item
{
float: left;
width:16px;
height: 16px;
background-image: url(./img/commstar.png);
}
.star>.star-con>.face{
width: 16px;
height: 16px;
background-image: url(./img/face-red.png);
position: absolute;
display: none;
}
.star>.score{
float: left;
display: block;
position: absolute;
right: -30px;
top: 16px;
width: 30px;
height: 16px;
line-height: 16px;
text-align: right;
color: #999;
}
`)
}
}
购物车
功能分析:
1.点击商品,自动加入购物车,点击次数决定购物车中商品数量
2.商品加入购物车后,商品信息数据分列显示,且总价根据商品数量以及商品单价计算
3.购物车有删除健,可以删除指定购物车中指定商品信息
4.有单选全选按钮,可以控制商品购买还是存放在购物车
5.购物车存在总价计算,通过单选全选按钮确认购买商品总价
<div class="goods-con"></div>
<div class="shopping-con"></div>
<script type="module">
var arr = [
{
id: "1001",
goods: [
{ id: 100101, img: "./img/100101.jpg", color: "冰岛幻境", title: "【京仓速发】送:壳膜+碎屏保+一年质保+晒单红包。4800万高感光夜拍三摄,光学屏幕指纹!旗舰新品荣耀50", price: 1628 },
{ id: 100102, img: "./img/100102.jpg", color: "幻夜黑", title: "【京仓速发】送:壳膜+碎屏保+一年质保+晒单红包。4800万高感光夜拍三摄,光学屏幕指纹!旗舰新品荣耀50", price: 1648 },
{ id: 100103, img: "./img/100103.jpg", color: "蓝水翡翠", title: "【京仓速发】送:壳膜+碎屏保+一年质保+晒单红包。4800万高感光夜拍三摄,光学屏幕指纹!旗舰新品荣耀50", price: 1698 },
],
promoteImg: "",
titleIcon: false,
title: "荣耀Play4T Pro/荣耀play4tpro 华为麒麟810芯片 全网通手机 冰岛幻境 8+128GB【碎屏险套装】",
info: ["8GB运存", "128GB"],
judge: 20000,
shopping: "佳沪电商旗舰店",
shoppingHref: "https://mall.jd.com/index-113406.html?from=pc",
icon: {
icon1: [],//红底白字
icon2: ["京东物流", "免邮", "赠"],//白底红字
icon3: [],
icon4: []
}
},
{
id: "1002",
goods: [
{ id: 100201, img: "./img/100201.jpg", color: "星空黑", title: "【自营】双灯强光手电筒.侧键开关/金属边框/4000mAh大电池.持久待机30天/一键解锁/一键报时/【365天以换代修】查看4G全网通版", price: 155 },
{ id: 100202, img: "./img/100202.jpg", color: "中国红", title: "【自营】双灯强光手电筒.侧键开关/金属边框/4000mAh大电池.持久待机30天/一键解锁/一键报时/【365天以换代修】查看4G全网通版", price: 155 },
{ id: 100203, img: "./img/100203.jpg", color: "悍马绿", title: "【自营】双灯强光手电筒.侧键开关/金属边框/4000mAh大电池.持久待机30天/一键解锁/一键报时/【365天以换代修】查看4G全网通版", price: 155 },
],
promoteImg: "./img/1002promoteImg.png|关注店铺即享115元|6.23-7.22",
titleIcon: false,
title: "纽曼 Newman L8 星空黑 三防老人手机超长待机 移动2G 直板按键大字大声 双卡双待老年机 学生儿童备用功能机",
info: ["8GB运存", "128GB"],
judge: 20000,
shopping: "纽曼京东自营官方旗舰店",
shoppingHref: "https://mall.jd.com/index-1000097221.html?from=pc",
icon: {
icon1: ["自营"],//红底白字
icon2: ["秒杀", "赠"],//白底红字
icon3: [],
icon4: []
}
},
{
id: "1003",
goods: [
{ id: 100301, img: "./img/100301.jpg", color: "液氧 ", title: "vivo X50", price: 2699 },
{ id: 100302, img: "./img/100302.jpg", color: "黑镜", title: "vivo X50", price: 2699 },
{ id: 100303, img: "./img/100303.jpg", color: "浅醺", title: "vivo X50", price: 2699 },
],
promoteImg: "",
titleIcon: false,
title: "vivo X50 5G手机 8+128GB 液氧 超感光夜摄 后置4800W像素 90Hz超薄柔性屏 双模5G全网通手机",
info: ["8GB运存", "128GB"],
judge: 20000,
shopping: "vivo京东自营官方旗舰店",
shoppingHref: "https://mall.jd.com/index-1000085868.html?from=pc",
icon: {
icon1: ["自营", "本地仓"],//红底白字
icon2: ["劵1350-95"],//白底红字
icon3: [],
icon4: []
}
},
{
id: "1004",
goods: [
{ id: 100401, img: "./img/100401.jpg", color: "曜岩黑 ", title: "限时优惠1300元,惊爆到手价7899元,下单还享12期免息!三星全系产品火热抢购中,欲购从速!", price: 7899 },
{ id: 100402, img: "./img/100402.jpg", color: "迷雾金", title: "限时优惠1300元,惊爆到手价7899元,下单还享12期免息!三星全系产品火热抢购中,欲购从速!", price: 7899 },
{ id: 100403, img: "./img/100403.jpg", color: "初露白", title: "限时优惠1300元,惊爆到手价7899元,下单还享12期免息!三星全系产品火热抢购中,欲购从速!", price: 7899 },
],
promoteImg: "",
titleIcon: false,
title: "三星 SAMSUNG Galaxy Note20 Ultra 5G(SM-N9860)5G手机 S Pen&三星笔记 120Hz 游戏手机 12GB+256GB 曜岩黑",
info: ["12GB运存", "256GB"],
judge: 20000,
shopping: "三星京东自营官方旗舰店",
shoppingHref: "https://mall.jd.com/index-1000003443.html?from=pc",
icon: {
icon1: ["自营"],//红底白字
icon2: [],//白底红字
icon3: [],
icon4: []
}
},
{
id: "1005",
goods: [
{ id: 100501, img: "./img/100501.jpg", color: "天空之境 ", title: "高速运行,适合学生,商务备用,后置1600万,自带美颜,强悍多核,应用多开,3900毫安电池强劲续航", price: 699 },
{ id: 100502, img: "./img/100502.jpg", color: "翡翠绿", title: "高速运行,适合学生,商务备用,后置1600万,自带美颜,强悍多核,应用多开,3900毫安电池强劲续航", price: 699 },
{ id: 100503, img: "./img/100503.jpg", color: "幻夜黑", title: "高速运行,适合学生,商务备用,后置1600万,自带美颜,强悍多核,应用多开,3900毫安电池强劲续航", price: 699 },
],
promoteImg: "",
titleIcon: false,
title: "小辣椒M12 Pro指纹一体游戏全网通4G大内存128G安卓学生高性价比千元机超长待机老人智能手机 天空之境 全网通[8G+128G]",
info: ["8GB运存", "128GB"],
judge: 20000,
shopping: "极客小酷旗舰店",
shoppingHref: "https://mall.jd.com/index-10137621.html?from=pc",
icon: {
icon1: [],//红底白字
icon2: [],//白底红字
icon3: [],
icon4: []
}
},
{
id: 1016,
goods: [
{ id: 101601, img: "./img/101601.jpg", color: "白色", title: "【手机、平板、笔记本旧机卖高价,加价红包快速回血】点击查看》》", price: 2579 },
{ id: 101602, img: "./img/101602.jpg", color: "黑色", title: "【手机、平板、笔记本旧机卖高价,加价红包快速回血】点击查看》》", price: 1999 },
],
promoteImg: "",
titleIcon: "flase",
title: "Apple iPhone X 苹果x二手手机 白色 256G ",
info: [],
judge: 20001,
shopping: "拍拍严选官方旗舰店",
shoppingHref: "https://mall.jd.com/index-10180819.html?from=pc",
incon: {
ico1: [],
ico2: ['2000-120'],
ico3: [],
ico4: [],
}
},
{
id: 1017,
goods: [
{ id: 101701, img: "./img/101701.png", color: "初雪水晶", title: "【荣耀官方直供】全国联保,大量现货,当天发货,赠中国荣耀定制壳+限量智能无线蓝牙耳机+原装碎屏险+水凝膜+运费险+2年保修荣耀50pro火爆抢购中", price: 2999 },
{ id: 101702, img: "./img/101702.jpg", color: "初雪水晶", title: "【荣耀官方直供】全国联保,大量现货,当天发货,赠中国荣耀定制壳+限量智能无线蓝牙耳机+原装碎屏险+水凝膜+运费险+2年保修荣耀50pro火爆抢购中", price: 2699 },
{ id: 101703, img: "./img/101703.jpg", color: "墨玉青", title: "【荣耀官方直供】全国联保,大量现货,当天发货,赠中国荣耀定制壳+限量智能无线蓝牙耳机+原装碎屏险+水凝膜+运费险+2年保修荣耀50pro火爆抢购中", price: 2699 },
{ id: 101704, img: "./img/101704.png", color: "墨玉青", title: "【荣耀官方直供】全国联保,大量现货,当天发货,赠中国荣耀定制壳+限量智能无线蓝牙耳机+原装碎屏险+水凝膜+运费险+2年保修荣耀50pro火爆抢购中", price: 2999 },
{ id: 101705, img: "./img/101705.jpg", color: "亮黑色", title: "【荣耀官方直供】全国联保,大量现货,当天发货,赠中国荣耀定制壳+限量智能无线蓝牙耳机+原装碎屏险+水凝膜+运费险+2年保修荣耀50pro火爆抢购中", price: 2699 },
],
promoteImg: "",
titleIcon: "flase",
title: "【荣耀官方直供】全国联保,大量现货,当天发货,赠中国荣耀定制壳+限量智能无线蓝牙耳机+原装碎屏险+水凝膜+运费险+2年保修荣耀50pro火爆抢购中",
info: [],
judge: 501,
shopping: "疆界互联旗舰店",
shoppingHref: "https://mall.jd.com/index-624094.html?from=pc",
incon: {
ico1: [],
ico2: ['京东物流', '秒杀', '赠'],
ico3: [],
ico4: [],
}
},
{
id: 1006,
goods: [
{ id: 100601, img: "./img/100601.jpg", color: "red", title: "【365天无忧换新】自营旗舰店!新品电信机来袭!国际大牌,低辐射,经久耐用,老年手机,超长待机,防滑机身,防尘按键,高亮手电,收音机/MP3娱乐》戳我看特价手机", price: 175 },
{ id: 100602, img: "./img/100602.jpg", color: "red", title: "【365天无忧换新】自营旗舰店!新品电信机来袭!国际大牌,低辐射,经久耐用,老年手机,超长待机,防滑机身,防尘按键,高亮手电,收音机/MP3娱乐》戳我看特价手机", price: 175 },
],
promoteImg: "",
titleIcon: false,
title: "飞利浦(PHILIPS)E109C 陨石黑 防尘 直板按键老人机 电信 老人手机 学生备用老年功能手机 儿童手机",
info: ["2GB以下运存", "8GB以下"],
judge: 50000,
shopping: "飞利浦手机京东自营旗舰店",
shoppingHref: "//mall.jd.com/index-1000013926.html?from=pc",
icon: {
icon1: ["自营"],//红底白字
icon2: ["秒杀", "赠"],//白底红字
icon3: [],//绿底白字
icon4: [],//白底蓝字
}
},
{
id: 1007,
goods: [
{ id: 100701, img: "./img/100701.jpg", color: "red", title: "", price: 158 },
],
promoteImg: "",
titleIcon: false,
title: "飞利浦(PHILIPS)E209 炫舞红 老人手机 移动/联通2G 超长待机 老年机大字大声学生备用功能机",
info: [""],
judge: 10000,
shopping: "飞利浦手机京东自营旗舰店",
shoppingHref: "//mall.jd.com/index-1000013926.html?from=pc",
icon: {
icon1: ["自营"],//红底白字
icon2: [],//白底红字
icon3: [],//绿底白字
icon4: [],//白底蓝字
}
},
{
id: 1008,
goods: [
{ id: 100801, img: "./img/100801.jpg", color: "red", title: "Apple iPhone苹果12【24期免息可选】5G全网通 黑色 128G(直播专属)", price: 5999 },
{ id: 100802, img: "./img/100802.jpg", color: "red", title: "Apple iPhone苹果12【24期免息可选】5G全网通 黑色 128G(直播专属)", price: 5999 },
{ id: 100803, img: "./img/100803.jpg", color: "red", title: "Apple iPhone苹果12【24期免息可选】5G全网通 黑色 128G(直播专属)", price: 6459 },
{ id: 100804, img: "./img/100804.jpg", color: "red", title: "Apple iPhone苹果12【24期免息可选】5G全网通 黑色 128G(直播专属)", price: 7079 },
{ id: 100805, img: "./img/100805.jpg", color: "red", title: "Apple iPhone苹果12【24期免息可选】5G全网通 黑色 128G(直播专属)", price: 6089 },
],
promoteImg: "",
titleIcon: false,
title: "Apple iPhone苹果12【24期免息可选】5G全网通 黑色 128G(直播专属)",
info: [""],
judge: 5000,
shopping: "京联通达旗舰店",
shoppingHref: "//mall.jd.com/index-643828.html?from=pc",
icon: {
icon1: [""],//红底白字
icon2: ["免邮"],//白底红字
icon3: [],//绿底白字
icon4: [],//白底蓝字
}
},
{
id: 1009,
goods: [
{ id: 100901, img: "./img/100901.jpg", color: "red", title: "护眼无蓝光,阅读更轻松!细致视觉体验!【TOUCH新配色登场】点击购买", price: 1999 },
{ id: 100902, img: "./img/100902.jpg", color: "red", title: "护眼无蓝光,阅读更轻松!细致视觉体验!【TOUCH新配色登场】点击购买", price: 1999 },
],
promoteImg: "./img/1009promoteImg.png|下单立减50|7.13-7.13",
titleIcon: false,
title: "海信(Hisense)A7 阅读手机A7 6.7英寸水墨屏 电纸书阅读器 6GB+128GB 全网通5G手机 曜石黑",
info: ["6GB运存", "128GB"],
judge: 10000,
shopping: "海信手机京东自营旗舰店",
shoppingHref: "/mall.jd.com/index-1000001978.html?from=pc",
icon: {
icon1: ["自营"],//红底白字
icon2: [],//白底红字
icon3: [],//绿底白字
icon4: [],//白底蓝字
}
},
{
id: 1010,
goods: [
{ id: 101001, img: "./img/101001.jpg", color: "red", title: "【用坏直接换新】送运费险,整点报时,支持一键拨号,来电报号8个亲情号码,一键手电筒", price: 78 },
{ id: 101002, img: "./img/101002.jpg", color: "red", title: "【用坏直接换新】送运费险,整点报时,支持一键拨号,来电报号8个亲情号码,一键手电筒", price: 78 },
{ id: 101003, img: "./img/101003.jpg", color: "red", title: "【用坏直接换新】送运费险,整点报时,支持一键拨号,来电报号8个亲情号码,一键手电筒", price: 155 },
{ id: 101004, img: "./img/101004.jpg", color: "red", title: "【用坏直接换新】送运费险,整点报时,支持一键拨号,来电报号8个亲情号码,一键手电筒", price: 109 },
{ id: 101005, img: "./img/101005.jpg", color: "red", title: "【用坏直接换新】送运费险,整点报时,支持一键拨号,来电报号8个亲情号码,一键手电筒", price: 109 },
{ id: 101006, img: "./img/101006.jpg", color: "red", title: "【用坏直接换新】送运费险,整点报时,支持一键拨号,来电报号8个亲情号码,一键手电筒", price: 155 },
],
promoteImg: "./img/1010promoteImg.png|限时抢 一年以换代修|7.19-7.19",
titleIcon: false,
title: "纽曼(Newman)T11全网通4G三防老人手机移动联通电信按键电霸老年机大声音大字体抗摔 持久续航 黑金色【移动版】",
info: ["2GB以下运存", "8GB以下"],
judge: 20000,
shopping: "纽曼手机旗舰店",
shoppingHref: "//mall.jd.com/index-826177.html?from=pc",
icon: {
icon1: [""],//红底白字
icon2: ["秒杀", "免邮"],//白底红字
icon3: [],//绿底白字
icon4: [],//白底蓝字
}
},
{
id: 1011,
goods: [
{ id: 101101, img: "img/101101.jpg", color: "black", title: "【JD自营】【3年只换不修】高端钢琴烤漆/祥云中框/震撼双超大喇叭/超长待机/双侧快捷键/2.5D大屏/全语音王/10个亲情号/大图大字大按键/购买红色", price: 199.00 },
],
promoteImg: "",
titleIcon: false,
title: "天语(K-Touch)N1 4G老人手机全网通",
info: [],
judge: 10000,
shopping: "天语手机京东自营官方旗舰店",
shoppingHref: "//mall.jd.com/index-1000089003.html?from=pc",
icon: {
icon1: ["自营"],//红底白字
icon2: ["秒杀", "赠"],//白底红字
icon3: [],//绿底白字
icon4: [],//白底蓝字
}
},
{
id: 1012,
goods: [
{ id: 101201, img: "img/101201.jpg", color: "red", title: "【自营】/早上买下午到/移动联通电信都能使用/翻盖接听/双电2600毫安/送长辈倍有面/购买黑色", price: 279.00 },
{ id: 101202, img: "img/101202.jpg", color: "black", title: "【自营】/早上买下午到/移动联通电信都能使用/翻盖接听/双电2600毫安/送长辈倍有面/购买黑色", price: 279.00 }
],
promoteImg: "",
titleIcon: false,
title: "天语(K-Touch)L660+ 全网通4G翻盖老人手机移动联通电信三网老人机超长待机备用功能老年手机 魅力红",
info: ["2GB以下运存", "8GB以下"],
judge: 10000,
shopping: "天语手机京东自营官方旗舰店",
shoppingHref: "//mall.jd.com/index-1000089003.html?from=pc?",
icon: {
icon1: ["自营"],//红底白字
icon2: ["赠"],//白底红字
icon3: [],//绿底白字
icon4: [],//白底蓝字
}
}, {
id: 1013,
goods: [
{ id: 101301, img: "img/101301.jpg", color: "white", title: "【JD自营】【3年只换不修】高端钢琴烤漆/祥云中框/震撼双超大喇叭/超长待机/双侧快捷键/2.5D大屏/全语音王/10个亲情号/大图大字大按键/购买红色", price: 799.00 },
],
promoteImg: "",
titleIcon: false,
title: "金立 Gionee M15Pro全网通4G超长待机6.5英寸水滴屏双卡双待老人学生智能手机 梦幻蓝 4GB+128GB",
info: [],
judge: 5000,
shopping: "极客小酷旗舰店",
shoppingHref: "//mall.jd.com/index-10137621.html?from=pc",
icon1: [],//红底白字
icon2: [],//白底红字
icon3: [],//绿底白字
icon4: [],//白底蓝字
},
{
id: 1014,
goods: [
{ id: 101401, img: "img/101401.jpg", color: "black", title: "【华为直供,全国联保1年,咨询客服送店铺延保1年,影视VIP】5G优畅享20", price: 5899.00 },
{ id: 101402, img: "img/101402.jpg", color: "black", title: "【华为直供,全国联保1年,咨询客服送店铺延保1年,影视VIP】5G优畅享20", price: 5899.00 },
{ id: 101403, img: "img/101403.jpg", color: "black", title: "【华为直供,全国联保1年,咨询客服送店铺延保1年,影视VIP】5G优畅享20", price: 5899.00 },
],
promoteImg: "",
titleIcon: false,
title: "华为mate40 5G手机 现货速发【支持鸿蒙HarmonyOs】 亮黑色 全网通(8GB+128GB) 碎屏险无线充套装",
info: [],
judge: 5000,
shopping: "京联通达旗舰店",
shoppingHref: "//item.jd.com/10025464286659.html?from=pc",
icon: {
icon1: [],//红底白字
icon2: ["免邮", "赠"],//白底红字
icon3: [],//绿底白字
icon4: [],//白底蓝字
}
},
{
id: 1015,
goods: [
{ id: 101501, img: "img/101501.jpg", color: "black", title: "OPPOK9套装今日秒杀直降130元至1869!+套装赠199元蓝牙音箱!+晒单赢20元京东E卡!65W超级闪充丨高通骁龙768G丨立即抢购", price: 1299.00 },
{ id: 101502, img: "img/101502.jpg", color: "black", title: "OPPOK9套装今日秒杀直降130元至1869!+套装赠199元蓝牙音箱!+晒单赢20元京东E卡!65W超级闪充丨高通骁龙768G丨立即抢购", price: 1299.00 },
{ id: 101503, img: "img/101503.jpg", color: "black", title: "OPPOK9套装今日秒杀直降130元至1869!+套装赠199元蓝牙音箱!+晒单赢20元京东E卡!65W超级闪充丨高通骁龙768G丨立即抢购", price: 1299.00 },
{ id: 101504, img: "img/101504.jpg", color: "black", title: "OPPOK9套装今日秒杀直降130元至1869!+套装赠199元蓝牙音箱!+晒单赢20元京东E卡!65W超级闪充丨高通骁龙768G丨立即抢购", price: 1299.00 },
{ id: 101505, img: "img/101505.jpg", color: "black", title: "OPPOK9套装今日秒杀直降130元至1869!+套装赠199元蓝牙音箱!+晒单赢20元京东E卡!65W超级闪充丨高通骁龙768G丨立即抢购", price: 1299.00 },
{ id: 101506, img: "img/101506.jpg", color: "black", title: "OPPOK9套装今日秒杀直降130元至1869!+套装赠199元蓝牙音箱!+晒单赢20元京东E卡!65W超级闪充丨高通骁龙768G丨立即抢购", price: 1299.00 },
],
promoteImg: "./img/1015-promote.png |赠199元蓝牙音箱!7.13-7.13",
titleIcon: false,
title: "【套装秒杀至高降130赠好礼!】OPPO K7x 5G新品手机90Hz电竞屏拍照游戏智能手机超级闪充 云之彼端套装 6GB+128GB",
info: ["6GB运行", "128GB"],
judge: 20000,
shopping: "OPPO官方直营旗舰店",
shoppingHref: "//mall.jd.com/index-793730.html?from=pc",
icon: {
icon1: [],//红底白字
icon2: ["京东物流", "秒杀", "赠"],//白底红字
icon3: [],//绿底白字
icon4: [],//白底蓝字
}
},
{
id: 1018,
goods: [
{ id: 101801, img: "./img/101801.jpg", color: "冲浪蓝孩", title: "爆品火热销售中!至高立省200元,到手价1149起!入会领10元优惠券!晒单赠10元红包!Q3系列新品全速来袭!", price: 1399 },
{ id: 101802, img: "./img/101802.jpg", color: "银翼少年", title: "爆品火热销售中!至高立省200元,到手价1149起!入会领10元优惠券!晒单赠10元红包!Q3系列新品全速来袭!", price: 1149 },
{ id: 101803, img: "./img/101803.jpg", color: "银翼少年", title: "爆品火热销售中!至高立省200元,到手价1149起!入会领10元优惠券!晒单赠10元红包!Q3系列新品全速来袭!", price: 1399 },
],
promoteImg: "./img/1018promote.png|限时立省200元 7.13-7.13",
titleIcon: "flase",
title: "realme 真我Q2 4800万像素 120Hz畅速屏 双5G天玑800U 学生潮玩手机 冲浪蓝孩",
info: [],
judge: 20001,
shopping: "realme真我官方旗舰店",
shoppingHref: "https://mall.jd.com/index-10099699.html?from=pc",
incon: {
ico1: [],
ico2: ['免邮', '劵39-10', '满1000-200'],
ico3: [],
ico4: [],
}
},
{
id: 1019,
goods: [
{ id: 101901, img: "./img/101901.jpg", color: "黑镜", title: "", price: 2649 },
],
promoteImg: "",
titleIcon: "flase",
title: "vivo X50 Pro 5G手机 vivo二手手机 60倍变焦 90Hz 黑镜 8G+256G ",
info: [],
judge: 1000001,
shopping: "拍拍严选官方旗舰店",
shoppingHref: "https://mall.jd.com/index-10180819.html?from=pc",
incon: {
ico1: [],
ico2: [],
ico3: [],
ico4: [],
}
},
{
id: 1020,
goods: [
{ id: 102001, img: "./img/102001.jpg", color: "晴空蓝", title: "购机补贴,合约立减,移动老用户和电信新用户下单就可享受优惠直降;电信成都,深圳,广州,东莞,杭州,温州,济南,南京,芜湖支持专人上门服务,更多城市即将上线", price: 599 },
],
promoteImg: "",
titleIcon: "flase",
title: "Redmi 9A 5000mAh大电量 大屏幕大字体大音量 1300万AI相机 八核处理器 人脸解锁 4GB+64GB 晴空蓝 游戏智能手机 小米 红米",
info: [],
judge: 200001,
shopping: "小米京东自营旗舰店",
shoppingHref: "https://mall.jd.com/index-1000004123.html?from=pc",
incon: {
icon1: ['自营'],
ico2: [],
ico3: [],
ico4: [],
}
},
{
goods: [
{ id: 102101, img: "./img/102101.jpg", color: "摩卡金", title: "【365天无忧换新】更大的2.8英寸屏!时尚设计,超大按键,百年国际品牌!一年只换不修!内外双屏,翻盖接听!大字体,大音量,语音播报,一键拨号!》戳我看典雅黑色", price: 249.00 },
],
id: 1021,
promoteImg: "",
titleIcon: false,
title: "飞利浦(PHILIPS)E219 摩卡金 翻盖老年手机 移动联通2G 双卡双待 老人手机 学生备用功能机 商务机 儿童机",
info: ["2GB以下运存", "8GB以下"],
judge: 20000,
shopping: "飞利浦手机京东自营旗舰店",
shoppingHref: "mall.jd.com/index-1000013926.html?from=pc",
icon: {
icon1: ["自营"],
icon2: ["秒杀", "赠"],
icon3: [],
icon4: [],
}
},
{
goods: [
{ id: 102201, img: "./img/102201.jpg", color: "曙光", title: "【7.13A95限时优惠200元到手价1799元|享6期免息丨店铺会员限时赠耳机|上手无忧】【OPPOK9限时优惠100元】立即点击", price: 1999.00 },
{ id: 102202, img: "./img/102202.jpg", color: "炫黑", title: "【7.13A95限时优惠200元到手价1799元|享6期免息丨店铺会员限时赠耳机|上手无忧】【OPPOK9限时优惠100元】立即点击", price: 1999.00 },
{ id: 102203, img: "./img/102203.jpg", color: "雅银", title: "【7.13A95限时优惠200元到手价1799元|享6期免息丨店铺会员限时赠耳机|上手无忧】【OPPOK9限时优惠100元】立即点击", price: 1999.00 },
],
id: 1022,
promoteImg: "./img/1022promote_img.png | 优惠200元丨6期免息",
titleIcon: false,
title: "OPPO A95 8+128GB 雅银 双模5G 4300mAh大电池 30W疾速快充 OLED超清护眼屏 4800万三摄 全面屏轻薄拍照手机",
info: ["8GB运存", "128GB"],
judge: 5000,
shopping: "OPPO京东自营官方旗舰店",
shoppingHref: "mall.jd.com/index-1000004065.html?from=pc",
icon: {
icon1: ["自营"],
icon2: ["秒杀", "券880-200"],
icon3: ["新品"],
icon4: [],
}
},
{
goods: [
{ id: 102301, img: "./img/102301.jpg", color: "黑色", title: "【用坏免费换】电话本报名字,读短信,强光手电,收音机,4000毫安电池超长待机,亲情号", price: 158.00 },
{ id: 102302, img: "./img/102302.jpg", color: "红色", title: "【用坏免费换】电话本报名字,读短信,强光手电,收音机,4000毫安电池超长待机,亲情号", price: 158.00 },
],
id: 1023,
promoteImg: "",
titleIcon: false,
title: "金立(Gionee)L9+移动联通电信版老人手机大字大声大音量 4G全网通老年手机直板按键备用机 红色 移动版【用坏免费换】",
info: [],
judge: 10000,
shopping: "弗瑞尔手机通讯专营店",
shoppingHref: "mall.jd.com/index-10022819.html?from=pc",
icon: {
icon1: [],
icon2: ["免邮"],
icon3: [],
icon4: [],
}
},
{
goods: [
{ id: 102401, img: "./img/102401.jpg", color: "砂石黑", title: "【下单赠壳膜套装】5000mAh大电量,大屏幕大字体大音量,1300万AI相机,八核处理器抢爆品荣耀Play3e", price: 599.00 },
{ id: 102402, img: "./img/102402.jpg", color: "晴空蓝", title: "【下单赠壳膜套装】5000mAh大电量,大屏幕大字体大音量,1300万AI相机,八核处理器抢爆品荣耀Play3e", price: 599.00 },
{ id: 102403, img: "./img/102403.jpg", color: "湖光绿", title: "【下单赠壳膜套装】5000mAh大电量,大屏幕大字体大音量,1300万AI相机,八核处理器抢爆品荣耀Play3e", price: 599.00 },
],
id: 1024,
promoteImg: "",
titleIcon: false,
title: "小米红米Redmi 9A 手机 5000mAh大电量 大屏幕大字体大音量1300万AI相机八核处理器 湖光绿 4GB+64GB",
info: ["4GB运存", "64GB"],
judge: 10000,
shopping: "伟德手机专营店",
shoppingHref: "//mall.jd.com/index-652270.html?from=pc",
icon: {
icon1: [],
icon2: ["京东物流", "免邮", "满599-15", "赠"],
icon3: [],
icon4: [],
}
},
{
goods: [
{ id: 102501, img: "./img/102501.jpg", color: "月魄", title: "", price: 1749.00 },
],
id: 1025,
promoteImg: "",
titleIcon: false,
title: "【白条12期免息】小米 红米note10pro 5G游戏手机 全网通 月魄 6GB+128GB【12期免息】送碎屏险",
info: ["2GB以下运存", "8GB以下"],
judge: 100,
shopping: "千瑞达手机旗舰店",
shoppingHref: "mall.jd.com/index-750688.html?from=pc",
icon: {
icon1: [],
icon2: [],
icon3: [],
icon4: [],
}
}
]
import Main from "./js/Main.js";
new Main(arr)
</script>
//Main.js
import Goods from "./Goods.js";
import ShoppingCar from "./ShoppingCar.js";
import StepNumber from "./StepNumber.js";
export default class Main{
goodsCon;
data;
shoppingList=[];
shoppingCar;
constructor(arr){
this.data=arr;
this.goodsCon = document.querySelector(".goods-con");
this.shoppingCon=document.querySelector(".shopping-con");
this.goodsCon.addEventListener(Goods.ADD_GOODS_EVENT,e=>this.addGoodsHandler(e));
this.shoppingCon.addEventListener(ShoppingCar.SELECT_GOODS_EVENT,e=>this.selectHandler(e))
this.shoppingCon.addEventListener(ShoppingCar.DELETE_GOODS_EVENT,e=>this.deleteHandler(e))
this.shoppingCon.addEventListener(StepNumber.STEP_CHANGE_EVENT,e=>this.stepChangeHandler(e))
arr.forEach(item => {
var goods = new Goods()
goods.setData(item)
goods.appendTo(this.goodsCon);
})
this.shoppingCar=new ShoppingCar();
this.shoppingCar.appendTo(this.shoppingCon);
}
addGoodsHandler(e){
var goods=this.shoppingList.find(item=>item.id===e.data.id);
if(!goods){
var obj={
id:e.data.id,
checked:false,
img:e.data.img,
title:e.data.title,
info:e.data.info.join(" "),
price:e.data.price,
num:1,
total:e.data.price,
del:false
}
this.shoppingList.push(obj);
}else{
goods.num++;
goods.total=goods.num*goods.price;
}
this.shoppingCar.update(this.shoppingList);
}
selectHandler(e){
if(e.id==="all"){
this.shoppingList.forEach(item=>{
item.checked=e.checked;
})
}else{
this.shoppingList.find(item=>item.id==e.id).checked=e.checked;
}
this.shoppingCar.update(this.shoppingList);
}
deleteHandler(e){
for(var i=0;i<this.shoppingList.length;i++){
if(this.shoppingList[i].id==e.id){
this.shoppingList.splice(i,1);
this.shoppingCar.update(this.shoppingList);
return;
}
}
}
stepChangeHandler(e){
this.shoppingList.forEach(item=>{
if(item.id==e.id){
item.num=e.step;
item.total=item.price*e.step;
}
})
this.shoppingCar.update(this.shoppingList);
}
}
//Goods.js
import Component from "./Component.js";
import Utils from "./Utils.js";
export default class Goods extends Component{
data;
prev;
static ADD_GOODS_EVENT="add_goods_event";
constructor(data){
super();
this.elem.className="goods"
this.setData(data)
Goods.setCss();
}
setData(data){
if(!data) return;
this.data=data;
this.elem.innerHTML=`
<a class='iconImg' ids='${data.goods[0].id}'><img src='${data.goods[0].img}'>${(()=>{
if(data.promoteImg.trim().length===0) return "";
var arr=data.promoteImg.split("|");
if(arr.length===1) return "<img class='iconPromote' title='"+data.goods[0].title+"' src='"+arr[0]+"'>";
return "<img class='iconPromote' src='"+arr[0]+"'><div class='iconPromoteTxt'>"+arr[1]+"</div>";
})()}</a>
<ul class='iconList clear'>${data.goods.reduce((value,item)=>{
return value+"<li><img title='"+item.color+"' src='"+item.img+"'></li>"
},"")}</ul>
<p class='priceCon'><span>¥</span><i>${data.goods[0].price.toFixed(2)}</i></p>
<p class='titleCon'><span class='${data.titleIcon ? "titleIcon" : ""}'>${data.titleIcon ? "京品手机" : ""}</span><a href='javascript:void(0)'><span class='title'>${data.title}</span></a></p>
<p class='info clear'>${data.info.reduce((value,item)=>{
value+="<span class='infoitem'>"+item+"</span>"
return value;
},"")}</p>
<div class='judgeCon'><span class='judge'>${data.judge>10000 ? Math.floor(data.judge/10000)+"万+" : data.judge}</span>条评价</div>
<div class='shoppingCon'><a class='shopping' href='${data.shoppingHref}'>${data.shopping}</a><img src='./img/chat.png'></div>
<div>${data.icon ? Object.keys(data.icon).reduce((value,prop)=>{
if(data.icon[prop].length===0) return value;
return value+data.icon[prop].reduce((v,t)=>{
return v+"<span class='"+prop+"'>"+t+"</span>"
},"")
},"") : ""}</div>
`
this.iconList=this.elem.querySelector(".iconList");
this.iconList.addEventListener("mouseover",e=>this.mouseHandler(e))
this.iconImg=this.elem.querySelector(".iconImg>img");
this.price=this.elem.querySelector(".priceCon>i");
var evt=new MouseEvent("mouseover",{bubbles:true});
this.iconList.children[0].firstElementChild.dispatchEvent(evt);
this.iconImg.addEventListener("click",e=>this.clickHandler(e));
}
clickHandler(e){
var goods=this.data.goods.find(item=>{
return item.id==e.target.parentElement.getAttribute("ids");
})
var obj={
id:goods.id,
img:goods.img,
price:goods.price,
title:goods.title,
info: this.data.info,
}
var evt=new Event(Goods.ADD_GOODS_EVENT,{bubbles:true});
evt.data=obj;
this.elem.dispatchEvent(evt);
}
mouseHandler(e){
if(e.target.nodeName!=="IMG") return;
if(this.prev){
this.prev.style.borderWidth="1px";
this.prev.style.borderColor="#DDD";
this.prev.style.padding="1px";
}
this.prev=e.target.parentElement;
this.prev.style.borderWidth="2px";
this.prev.style.borderColor="#e4393c";
this.prev.style.padding="0px";
var index=Array.from(this.iconList.children).indexOf(this.prev);
this.iconImg.src=this.data.goods[index].img;
this.price=this.data.goods[index].price.toFixed(2);
this.iconImg.title=this.data.goods[index].title;
this.iconImg.parentElement.setAttribute("ids",this.data.goods[index].id)
}
static setCss(){
if(super.setCss()) return;
Utils.setCss(`.goods{
width: 240px;
height: 444px;
padding: 12px 9px;
font: 12px/150% tahoma,arial,Microsoft YaHei,Hiragino Sans GB,"\u5b8b\u4f53",sans-serif;
color: #666;
position: relative;
float: left;
}
.goods:hover{
box-shadow: 0px 0px 4px #CCC;
}
.goods>.iconImg{
text-decoration: none;
width: 100%;
height: 220px;
text-align: center;
display: block;
position: relative;
}
.goods>.iconImg>img{
width: 220px;
height: 220px;
}
.goods>.iconImg>.iconPromote{
width: 220px;
height: 42px;
position: absolute;
bottom: 0;
left:0;
}
.goods>.iconImg>.iconPromoteTxt{
position: absolute;
bottom: 0;
left:0;
width: 220px;
line-height: 30px;
text-align: center;
color: white;
}
.goods>.iconList{
list-style: none;
margin: 0;
padding: 0;
margin-left: 2px;
}
.goods>.iconList>li{
float:left;
/* #e4393c */
border: 1px solid #ddd;
padding: 1px;
width:25px;
height: 25px;
margin: 2px;
}
.goods>.iconList>li>img{
width: 25px;
height: 25px;
}
.clear::after
{
content: "";
display: block;
height: 0;
overflow: hidden;
clear: both;
visibility: hidden;
}
.goods>.priceCon{
font-size: 16px;
color: #e4393c;
margin: 0;
margin-top: 8px;
}
.goods>.priceCon>i{
font-size: 20px;
font-style: normal;
font-weight: 400;
font-family: Verdana;
}
.goods>.titleCon{
width: 220px;
overflow: hidden;
white-space: nowrap;
margin: 0;
margin-top: 8px;
padding: 0;
}
.goods>.titleCon>.titleIcon{
float: left;
height: 16px;
padding: 0 3px;
margin-top: 2px;
margin-right: 3px;
overflow: hidden;
color: #fff;
font: 12px/16px "Helvetica Neue","Hiragino Sans GB",SimSun,serif;
background: #c81623;
border-radius: 2px;
}
.goods>.titleCon>a{
text-decoration: none;
color: #666;
}
.goods>.titleCon>a:hover{
color: #c81623;
}
.goods>.info{
margin: 0;
margin-top: 8px;
}
.goods>.info>.infoitem{
float: left;
height: 19px;
line-height: 19px;
padding: 0 4px;
margin-right: 7px;
background: #f4f4f4;
}
.goods>.judgeCon{
margin-top: 8px;
}
.goods>.judgeCon>.judge
{
color: #646fb0;
font-family: verdana;
font-weight: 700;
}
.goods>.shoppingCon{
margin-top: 8px;
margin-bottom: 10px;
}
.goods>.shoppingCon>.shopping{
color: #999;
text-decoration: none;
display: inline-block;
max-width: 122px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.goods>.shoppingCon>.shopping:hover{
color: #c81623;
}
.icon1,.icon3{
float: left;
height: 16px;
line-height: 16px;
padding: 0 3px;
margin-right: 3px;
overflow: hidden;
text-align: center;
font-style: normal;
font-size: 12px;
font-family: "Helvetica Neue","Hiragino Sans GB",SimSun,serif;
background: #e23a3a;
color: #FFF;
cursor: default;
border-radius: 2px;
}
.icon2{
float: left;
height: 14px;
line-height: 14px;
padding: 0 3px;
border: 1px solid #e23a3a;
margin-right: 3px;
overflow: hidden;
text-align: center;
font-style: normal;
font-size: 12px;
font-family: "Helvetica Neue","Hiragino Sans GB",SimSun,serif;
border-radius: 2px;
color: #e23a3a;
}
.icon3{
background: #31c19e;
}
.icon4{
}`)
}
}
//ShoppingCar.js
import Component from "./Component.js";
import StepNumber from "./StepNumber.js";
export default class ShoppingCar extends Component{
head=["全选","","商品","","单价","数量","小计","操作"];
tbody;
all;
static SELECT_GOODS_EVENT="select_goods_event";
static DELETE_GOODS_EVENT="delete_goods_event";
constructor(){
super("table");
this.elem.innerHTML=`
<thead>
<tr>
${this.head.reduce((value,item,index)=>{
if(index===1) return value;
return value+"<th "+(index===0 ? "colspan='2'" : "")+">"+(index===0 ? "<input class='all' type='checkbox'>" : "")+item+"</th>";
},"")}
</tr>
</thead>
<tbody>
</tbody>
<tfoot>
<tr><td></td></tr>
</tfoot>
`
this.tbody=this.elem.querySelector("tbody");
this.tfootd=this.elem.querySelector("tfoot td");
this.all=this.elem.querySelector(".all");
this.all.addEventListener("click",e=>this.clickHandler(e));
}
update(list){
this.tbody.innerHTML="";
this.all.checked=list.every(item=>item.checked);
var elem=document.createDocumentFragment();
for(var i=0;i<list.length;i++){
var tr=document.createElement("tr");
for(var prop in list[i]){
if(prop==="id")continue;
var td=document.createElement("td");
this.setTDData(td,list[i],prop);
tr.appendChild(td);
}
elem.appendChild(tr);
}
this.tbody.appendChild(elem);
this.tfootd.textContent=list.reduce((value,item)=>{
if(item.checked) return value+item.total;
return value;
},0);
}
setTDData(td,data,prop){
switch(prop){
case "checked":
var input=document.createElement("input");
input.type="checkbox";
input.checked=data.checked;
input.data=data;
input.addEventListener("click",e=>this.clickHandler(e));
td.appendChild(input);
break;
case "img":
var img=new Image();
img.src=data.img;
Object.assign(img.style,{
width:"80px",
height:"80px"
})
td.appendChild(img);
break;
case "price":
case "total":
td.textContent="¥"+data[prop].toFixed(2);
break;
case "del":
var a=document.createElement("a");
a.textContent="删除";
a.href="javascript:void(0)"
td.appendChild(a);
a.addEventListener("click",e=>{
var evt=new Event(ShoppingCar.DELETE_GOODS_EVENT,{bubbles:true});
evt.id=data.id;
a.dispatchEvent(evt)
})
break;
case "num":
var step=new StepNumber(data);
step.setStep(data.num);
step.appendTo(td);
break;
default:
td.textContent=data[prop];
}
}
clickHandler(e){
var ck=e.currentTarget;
var evt=new Event(ShoppingCar.SELECT_GOODS_EVENT,{bubbles:true});
evt.id=ck===this.all ? "all" : ck.data.id;
evt.checked=ck.checked;
this.elem.dispatchEvent(evt);
}
}