购物车操作页面
css样式文档main.css
html {
background-color: #eeeeee;
}
.goodsCon {
width: 290px;
height: 400px;
background-color: white;
float: left;
margin-left: 10px;
margin-bottom: 10px;
position: relative;
}
.icon {
width: 200px;
height: 200px;
margin: auto;
position: absolute;
left: 0;
right: 0;
top: 30px;
transition: all 0.3s;
}
.icon:hover {
top: 20px;
}
.title {
color: #333;
font-size: 14px;
margin: 20px -10px 9px;
font-weight: 400;
text-align: left;
line-height: 20px;
height: 20px;
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
position: absolute;
left: 30px;
top: 230px;
width: 240px;
}
.info {
position: absolute;
top: 275px;
left: 20px;
color: #e01222;
font-size: 14px;
}
.info > img {
width: 40px;
height: 19px;
vertical-align: middle;
margin-right: 10px;
}
.priceCon {
width: 290px;
height: 100px;
position: absolute;
border-top: 1px solid #eeeeee;
top: 300px;
}
.history {
position: absolute;
left: 20px;
top: 6px;
padding: 0 8px;
height: 16px;
line-height: 16px;
background-color: #e6e6e6;
font-size: 10px;
color: #999;
-moz-border-radius: 2px;
border-radius: 2px;
}
.price {
font-size: 24px;
color: #e01222;
display: inline-block;
margin-top: 25px;
margin-left: 20px;
}
.price::first-letter {
font-size: 14px;
}
.oldPrice {
font-size: 12px;
color: #999999;
text-decoration: line-through;
display: inline-block;
margin-left: 6px;
}
.soldText {
margin-left: 20px;
font-size: 12px;
color: #666666;
}
.soldSpan {
width: 88px;
height: 8px;
display: inline-block;
background-color: #e6e6e6;
margin-left: 10px;
border-radius: 4px;
}
.soldSpan > span {
display: block;
background-color: #e01222;
height: 8px;
border-radius: 4px;
}
.button {
color: #fff;
height: 40px;
line-height: 40px;
font-size: 16px;
display: block;
top: 0;
right: 0;
bottom: 0;
margin: auto 0;
width: 80px;
text-align: center;
position: absolute;
background: #df0021;
text-decoration: none;
}
商品信息
Goddsltem.js文档
import Utils from "./Utils.js";
export default class GoodsItem extends EventTarget{
elem;
data;
static ADD_GOODS_EVENT="add_goods_event";
constructor(_data){
super();
this.data=_data;
this.elem=this.createElem(_data);
}
appendTo(parent){
if(typeof parent==="string"){
parent=document.querySelector(parent);
}
parent.appendChild(this.elem);
}
createElem(data){
var div = Utils.ce("div");
div.className = "goodsCon";
var a=Utils.ce("a");
a.addEventListener("click",e=>this.clickHandler(e));
a.target="_blank";
div.appendChild(a);
this.createIcon(a, data.icon);
this.createTitle(a, data.title);
this.createInfo(a, data.info, data.selfSell);
this.createPriceCon(div, data);
return div;
}
createIcon(parent, iconPath) {
var img = new Image();
img.src = iconPath;
img.className = "icon";
parent.appendChild(img);
}
createTitle(parent, title) {
var h4 = Utils.ce("h4");
h4.className = "title";
h4.textContent = title;
parent.appendChild(h4);
}
createInfo(parent, info, selfSell) {
var div = Utils.ce("div");
if (selfSell) {
var img = new Image();
img.src = "./img/self.png";
div.appendChild(img);
}
var text = document.createTextNode(info);
div.appendChild(text);
div.className = "info";
parent.appendChild(div);
}
createPriceCon(parent, data) {
var div = Utils.ce("div");
div.className = "priceCon";
this.createHistory(div, data.history);
this.createPrice(div, data.price, data.oldPrice);
this.createsold(div, data.sold);
this.createButton(div, data.href);
parent.appendChild(div);
}
createHistory(parent, history) {
if(history.trim().length===0) return;
var div = Utils.ce("div");
div.textContent = history;
div.className = "history";
parent.appendChild(div);
}
createPrice(parent, price, oldPrice) {
var priceDiv = Utils.ce("span");
priceDiv.textContent = "¥" + price;
priceDiv.className = "price";
var oldPriceDiv = Utils.ce("span");
oldPriceDiv.textContent = "¥" + oldPrice;
oldPriceDiv.className = "oldPrice";
parent.appendChild(priceDiv);
parent.appendChild(oldPriceDiv);
}
createsold(parent, sold) {
var div = Utils.ce("div");
var soldText = Utils.ce("span");
soldText.textContent = `已售${sold * 100}%`;
soldText.className = "soldText";
div.appendChild(soldText);
var soldSpan = Utils.ce("span");
var soldRed = Utils.ce("span");
soldSpan.className = "soldSpan";
soldRed.style.width = 88 * sold + "px";
soldSpan.appendChild(soldRed);
div.appendChild(soldSpan);
parent.appendChild(div);
}
createButton(parent, href) {
var a = Utils.ce("a");
a.addEventListener("click",e=>this.clickHandler(e));
a.textContent = "立即抢购";
a.className = "button";
a.target="_blank";
parent.appendChild(a);
}
clickHandler(e){
var evt=new Event(GoodsItem.ADD_GOODS_EVENT);
this.dispatchEvent(evt);
}
}
数量选择框
StepNumber.js文档
import Utils from "./Utils.js";
export default class StepNumber{
elem;
input;
ids;
step = 1;
obj;
constructor(_obj) {
this.obj=_obj;
this.elem = this.createElem();
}
createElem() {
let div = Utils.ce("div", {
width: "80px",
height: "22px",
position: "relative",
margin:"auto"
});
this.createBnList(div);
this.cteateInput(div);
return div;
}
createBnList(parent) {
var leftBn = Utils.ce("div", {
width: "15px",
height: "20px",
position: "absolute",
textAlign: "center",
userSelect: "none",
backgroundColor:"#FFF",
border: "1px solid #CCCCCC"
});
var rightBn = leftBn.cloneNode(false);
leftBn.style.left = "0px";
rightBn.style.right = "0px";
leftBn.textContent = "-";
rightBn.textContent = "+";
parent.appendChild(leftBn);
parent.appendChild(rightBn);
leftBn.addEventListener("click", e => this.clickHandler(e));
rightBn.addEventListener("click", e => this.clickHandler(e));
}
cteateInput(parent) {
this.input = Utils.ce("input", {
width: "46px",
height: "18px",
position: "absolute",
left: "17px",
border: "none",
textAlign: "center",
borderTop: "1px solid #CCCCCC",
borderBottom: "1px solid #CCCCCC"
});
this.input.value = "1";
parent.appendChild(this.input);
this.input.addEventListener("input", e => this.inputHandler(e));
}
appendTo(parent) {
if (typeof parent === "string") {
parent = document.querySelector(parent);
}
parent.appendChild(this.elem);
}
inputHandler(e) {
this.input.value = this.input.value.replace(/\D/g, "");
if (this.ids) return;
this.ids = setTimeout(() => {
clearTimeout(this.ids);
this.ids = 0;
this.setStep(this.input.value);
this.dispatch();
}, 500);
}
clickHandler(e) {
if (e.currentTarget.textContent === "-") {
this.setStep(this.step - 1);
} else {
this.setStep(this.step + 1);
}
this.dispatch();
}
setStep(value) {
value = Number(value);
if (value < 1) value = 1;
if (value > 999) value = 999;
this.step = value;
this.input.value = this.step;
}
dispatch(){
var evt=new Event("step_change");
evt.step=this.step;
evt.elem=this.elem;
evt.obj=this.obj;
document.dispatchEvent(evt);
}
}
创建容器
Utils.js文档
export default class Utils{
static ce(type,style){
let elem=document.createElement(type);
Object.assign(elem.style,style);
return elem;
}
}
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
.divs{
width: 1200px;
margin: auto;
}
.tables{
width: 1200px;
border-collapse: collapse;
margin: auto;
font-size: 12px;
color: #666666;
}
.thr{
background-color: #f3f3f3;
color: #666666;
font-size: 12px;
height: 50px;
border: 1px solid #ccc;
}
[type=checkbox]{
vertical-align: middle;
}
.thr > th:nth-child(1) {
width: 60px;
}
.thr > th:nth-child(2) {
width: 120px;
}
.thr > th:nth-child(3) {
width: 300px;
}
.thr > th:nth-child(4) {
width: 180px;
}
.thr > th:nth-child(5) {
width: 120px;
}
.thr > th:nth-child(6) {
width: 180px;
}
.thr > th:nth-child(7) {
width: 120px;
}
a {
text-decoration: none;
}
a {
color: #666666;
}
td>a:hover{
color: red;
}
tr {
background-color: #fff4e8;
border: 1px solid #cccccc;
}
.sumValue{
font-size: 24px;
color: red;
text-align: right;
padding-right: 120px;
}
.Sum{
width: 200px;
}
</style>
<!-- 引入css样式文档 -->
<link href="./css/main.css" rel="styleSheet">
</head>
<body>
<div class="divs"></div>
<script type="module">
import GoodsItem from "./js/GoodsItem.js";
import Utils from "./js/Utils.js";
import StepNumber from "./js/StepNumber.js";
var goodsList = [
{
id: 1001,
icon: "./img/a.jpg",
title: "水悟月【请财运】和田玉聚财貔貅",
info: "送手串 顺丰发货",
selfSell: false,
history: "1年历史最低价",
oldPrice: "993",
price: "298",
sold: 0.8,
href: "https://item.jd.com/34622502992.html",
},
{
id: 1002,
icon: "./img/b.jpg",
title: "YAYA鸭鸭服饰时尚卫衣休闲裤套装",
info: "125元2套185元3套",
selfSell: false,
history: "49天历史最低价",
oldPrice: "199",
price: "65",
sold: 0.97,
href: "https://item.jd.com/100005009278.html",
},
{
id: 1003,
icon: "./img/c.jpg",
title: "MK羊皮革黑色斜挎包",
info: "",
selfSell: true,
history: "51天历史最低价",
oldPrice: "2280",
price: "1550",
sold: 0.34,
href: "https://item.jd.com/34622502992.html",
},
{
id: 1004,
icon: "./img/d.jpg",
title: "卡帝乐鳄鱼|99元超值5件装",
info: "99元5件|100%纯棉",
selfSell: false,
history: "",
oldPrice: "288",
price: "99",
sold: 0.99,
href: "https://item.jd.com/100005009278.html",
},
{
id: 1005,
icon: "./img/e.jpg",
title: "【限量抢】男童女童薄款牛仔防蚊裤|99元超值5件装",
info: "2条9折",
selfSell: false,
history: "30天历史最低价",
oldPrice: "98",
price: "39",
sold: 0.25,
href: "https://item.jd.com/34622502992.html",
},
{
id: 1006,
icon: "./img/f.jpg",
title: "迪士尼幼儿科学大揭秘绘本全12册",
info: "同享每满100减50",
selfSell: true,
history: "32天历史最低价",
oldPrice: "126",
price: "100",
sold: 0.36,
href: "https://item.jd.com/100005009278.html",
},
{
id: 1007,
icon: "./img/g.jpg",
title: "上林春天 实木书桌带书架",
info: "下单送台灯",
selfSell: false,
history: "331天历史最低价",
oldPrice: "658",
price: "588",
sold: 0.26,
href: "https://item.jd.com/34622502992.html",
},
{
id: 1008,
icon: "./img/h.jpg",
title: "买一送一\薄款休闲裤男特价78元",
info: "限时抢购200条",
selfSell: false,
history: "",
oldPrice: "158",
price: "78",
sold: 0.99,
href: "https://item.jd.com/100005009278.html",
},
];
var table;
var headTilte = ["全选", "", "商品", "", "单价", "数量", "小计", "操作"];
var data=[];
init();
function init(){
document.addEventListener("step_change",StepChangeHandler);
goodsList.forEach(item=>{
let goods=new GoodsItem(item);
goods.appendTo(".divs");
goods.addEventListener(GoodsItem.ADD_GOODS_EVENT,addGoodsHandler);
});
}
function addGoodsHandler(e){
var o = this.data;
var arr=data.filter(item=>{
return item.id===o.id;
});
if(arr.length===0){
var obj={
id:o.id,
selected: false,
icon: o.icon,
title: o.title,
info: o.info,
price: Number(o.price),
num: 1,
sum: Number(o.price),
del: false,
};
data.push(obj);
}else{
arr[0].num++;
arr[0].sum=arr[0].num*arr[0].price;
}
createTable();
}
function createTable(){
if(table){
table.remove();
table=null;
}
table=Utils.ce("table");
table.className="tables";
createHead(table);
createContent(table);
createTableFoot(table);
document.body.appendChild(table);
}
function createHead(parent){
var tr=Utils.ce("tr");
for(var i=0;i<headTilte.length;i++){
if(i===1 || i===3) continue;
var th=Utils.ce("th");
if(i===0 || i===2) th.setAttribute("colspan","2");
th.textContent=headTilte[i];
if(headTilte[i]==="全选"){
var ck=Utils.ce("input");
ck.type="checkbox";
ck.checked=data.every(item=>item.selected);
ck.addEventListener("click",selectedClickHandler);
th.appendChild(ck);
th.insertBefore(ck,th.firstChild);
}
tr.appendChild(th);
}
tr.className="thr";
parent.appendChild(tr);
}
function createContent(parent){
for(var i=0;i<data.length;i++){
var obj=data[i];
var tr=Utils.ce("tr");
tr.style.height="100px";
for(var prop in obj){
if(prop==="id") continue;
var td=Utils.ce("td");
createTdContent(td,obj,prop);
tr.appendChild(td);
}
parent.appendChild(tr);
}
}
function createTdContent(td,obj,prop){
switch(prop){
case "selected":
var ck=Utils.ce("input");
ck.type="checkbox";
ck.obj=obj;
ck.checked=obj[prop];
ck.addEventListener("click",selectedClickHandler);
td.appendChild(ck);
td.style.paddingLeft="10px";
break;
break;
case "icon":
var img=new Image();
img.src=obj[prop];
img.style.width = "80px";
img.style.height = "80px";
td.appendChild(img);
break;
break;
case "price":
case "sum":
td.textContent="¥"+Number(obj[prop]).toFixed(2);
td.style.textAlign="center";
break;
break;
case "del":
var a = Utils.ce("a");
a.href = "javascript:void(0)";
a.textContent = "删除";
a.obj=obj;
a.addEventListener("click",delClickHandler);
td.appendChild(a);
td.style.textAlign="center";
break;
case "num":
let step=new StepNumber(obj);
step.appendTo(td);
step.setStep(obj[prop]);
break;
default:
td.textContent=obj[prop];
td.style.textAlign = "center";
}
}
function createTableFoot(parent){
var tr=Utils.ce("tr");
tr.style.height="80px";
for(var i=0;i<5;i++){
var td=Utils.ce("td");
if(i===0) createDelShopping(td);
if(i===2) createShoppingCount(td);
if(i===3) createSum(td);
if(i===4) createSubmit(td);
tr.appendChild(td);
}
parent.appendChild(tr);
}
function createDelShopping(td){
var ck=Utils.ce("input");
ck.type="checkbox";
ck.style.marginLeft="12px";
ck.checked=data.every(item=>item.selected);
ck.addEventListener("click",selectedClickHandler);
td.appendChild(ck);
td.setAttribute("colspan","4");
var span=Utils.ce("span");
span.textContent="全选";
var a=Utils.ce("a");
a.textContent="删除选中商品";
a.style.marginLeft="5px";
a.href = "javascript:void(0)";
a.addEventListener("click",deleteClickHandler);
td.appendChild(a);
var a=Utils.ce("a");
a.textContent="清理购物车";
a.style.marginLeft="5px";
a.href="javascript:void(0)";
a.addEventListener("click",deleteClickHandler);
td.appendChild(a);
}
function createShoppingCount(td){
var span1=Utils.ce("span");
span1.textContent="已选择";
var span2=Utils.ce("span",{
color:"red",
});
span2.textContent=data.filter(item=>item.selected).length;
var span3=Utils.ce("span");
span3.textContent="件商品";
td.appendChild(span1);
td.appendChild(span2);
td.appendChild(span3);
}
function createSum(td){
var span=Utils.ce("span",{
fontSize:"18px"
});
span.textContent="总价:";
var span1=Utils.ce("span",{
fontSize:"24px",
color:"red",
});
span1.textContent="¥"+data.reduce((value,item)=>{
if(item.selected) return value+item.sum;
return value;
},0).toFixed(2);
td.className="Sum";
td.appendChild(span);
td.appendChild(span1);
}
function createSubmit(td){
var span=Utils.ce("span",{
fontSize:"24px",
color:"red",
marginLeft:"20px",
border:"1px solid #fff",
backgroundColor:"#666"
});
span.textContent="结算";
td.appendChild(span);
}
function delClickHandler(e){
data=data.filter(item=>{
return e.currentTarget.obj.id!==item.id;
});
createTable();
}
function selectedClickHandler(e){
var ck=e.currentTarget;
if(ck.obj){
ck.obj.selected=ck.checked;
}else{
data.forEach(item=>{
item.selected=ck.checked;
});
}
createTable();
}
function StepChangeHandler(e){
var id=e.obj.id;
var num=e.step;
data.forEach(item=>{
if(item.id===id){
item.num=num;
item.sum=num*item.price;
}
})
createTable();
}
function deleteClickHandler(e){
if(e.currentTarget.textContent==="删除选中商品"){
data=data.filter(item=>{
return !item.selected;
});
}else{
data.length=0;
}
createTable();
}
</script>
</body>
</html>