ionic4.x仿京东 - 10.1.购物车-商品属性选择、添加到购物车
一、商品属性选择
1.【pcontent.page.html】
找到attr这个div,整个用一个div包裹住,命名为myAttr,监听点击事件叫changeAttr($event),传入事件对象event
2.【pcontent.page.ts】
(1)看看e到底是什么
将e.srcElement打印出来,控制台输出:(获取到当前点击的元素的节点,原生JS)
将e.srcElement.nodeName打印出来,控制台输出:(获取到当前点击的元素的节点的标签名,原生JS)
(2)筛选span标签,并给它加class='active'的样式
【pcontent.page.ts】
【pcontent.page.scss】
找到span标签,加active的样式
active样式:加红色边框
效果:
(3)选中哪个,只给当前加边框,其他兄弟节点不加
思路:获取父节点,父节点的所有子节点不加active,只给当前节点加active
效果:
(4)默认选第一个
对<span>循环遍历,let key=index;---用key获取索引值
[ngClass]="{'active': key==0}" ---当key==0时,赋予active属性
二、数量加减
1.商品属性:数量的双向绑定
原来:
把id去掉,换成ng-model:
三、加入购物车
控制台输出:
- 代码详解
把spanActive打印出来:
spanActive是个数组:
spanActive[i].innerHTML见上
最终代码
【pcontent.page.html】
<ion-header>
<ion-toolbar>
<ion-buttons slot="start">
<ion-back-button defaultHref="/tabs/tab1" color="dark"></ion-back-button>
</ion-buttons>
<ion-segment value="pizza" [(ngModel)]="tab" color="danger">
<ion-segment-button value="list">
<ion-label>商品</ion-label>
</ion-segment-button>
<ion-segment-button value="content">
<ion-label>详情</ion-label>
</ion-segment-button>
</ion-segment>
</ion-toolbar>
</ion-header>
<ion-content>
<div [ngSwitch]="tab" class="p_content">
<!-- 商品 -->
<div *ngSwitchCase="'list'" class="con_1">
<div class="p_img" *ngIf="list.pic">
<img [src]="config.domain + list.pic">
</div>
<div class="p_info mb10">
<!-- mb10表示和底部栏10px距离,在公共样式global.scss里定义 -->
<div class="p_title">
<h2>{{list.title}}</h2>
<p>{{list.sub_title}}</p>
</div>
<div class="product_price mb10">
<span class="now_price">
特价:
<span class="price">¥{{list.price}}</span>
</span>
原价:
<span class="old_price">¥{{list.old_price}}</span>
</div>
</div>
<div class="p_attr mb10">
<div class="myAttr" (click)="changeAttr($event)">
<div class="attr" *ngFor="let items of list.attr">
<strong>{{items.cate}}:</strong>
<span [ngClass]="{'active': key==0}" *ngFor="let attr of items.list; let key=index;">{{attr}}</span>
</div>
</div>
<div class="number">
<strong>数量:</strong>
<div class="cart_number">
<div class="input_left" (click)="decNum()">-</div>
<div class="input_center">
<input type="text" readonly="readonly" value="1" name="num" [(ngModel)]="num">
</div>
<div class="input_right" (click)="incNum()">+</div>
</div>
</div>
</div>
<div class="fee mb10">
运费:免运费
</div>
</div>
<!-- 详情 -->
<div *ngSwitchCase="'content'" class="con_2">
<div [innerHTML]='list.content'>
</div>
</div>
</div>
</ion-content>
<ion-footer>
<ion-toolbar>
<div class="footer_bar">
<div class="carticon">
<ion-icon slot="start" name="cart"></ion-icon>
<p>购物车</p>
<ion-badge color="danger" mode="ios">1</ion-badge>
</div>
<div class="addcart" (click)="addCart()">
加入购物车
</div>
<div class="buy">
立即购买
</div>
</div>
</ion-toolbar>
</ion-footer>
【pcontent.page.scss】
.footer_bar {
display: flex;
.carticon {
width: 6.6rem;
position: relative;
text-align: center;
ion-icon {
color: #999;
font-size: 2.8rem;
}
p {
color: #999;
text-align: center;
font-size: 1.4rem;
}
ion-badge {
position: absolute;
right: .3rem;
top: -.2rem;
}
}
.addcart {
flex: 1;
height: 4rem;
text-align: center;
background: orange;
color: #fff;
line-height: 4rem;
}
.buy {
flex: 1;
height: 4rem;
text-align: center;
background: red;
color: #fff;
line-height: 4rem;
}
}
// 商品详情页面的布局
.p_content {
background: #efefef;
// 商品
.con_1 {
.p_img {
width: 100%;
max-height: 15rem;
img {
width: 100%;
max-height: 15rem;
}
}
// 标题 价格
.p_info {
background: #fff;
padding: .5rem;
.p_title {
padding-bottom: .5rem;
h2 {
font-size: 1.6rem;
line-height: 1.5;
padding-bottom: .5rem;
}
p {
font-size: 1.4rem;
color: #666;
line-height: 1.5;
}
}
.product_price {
.now_price {
.price {
color: red;
font-size: 2.0rem;
}
}
.old_price {
color: #666;
font-size: 1.4rem;
text-decoration: line-through;
}
}
}
// 属性
.p_attr {
background: #fff;
padding: .5rem;
padding-bottom: 2rem;
.attr {
padding-bottom: .5rem;
span {
// span是行内元素,只能margin左右,不能上下,解决方法:display: inline-block;行内块
border: 1px solid #eee;
border-radius: .5rem;
padding: .5rem 1rem;
display: inline-block;
margin: .4rem;
&.active {
border: 2px solid red;
}
}
}
.number {
.cart_number {
float: right;
width: 10rem;
display: flex;
.input_left, .input_right {
width: 3.8rem;
height: 2.8rem;
line-height: 2.8rem;
text-align: center;
background: #f8f8f8;
border: 1px solide #f8f8f8;
}
.input_center {
flex: 1;
height: 2.8rem;
line-height: 2.8rem;
input {
border: 1px solid #f8f8f8;
height: 2.8rem;
line-height: 2.8rem;
width: 100%;
text-align: center;
}
}
}
}
}
// 运费
.fee {
background: #fff;
padding: .5rem;
margin-bottom: 2rem;
}
}
// 详情
.con_2 {
background: #fff;
line-height: 2;
padding: .5rem;
img {
max-width: 90%;
display: block;
margin: 0 auto;
}
}
}
【pcontent.page.ts】
import { Component, OnInit } from '@angular/core';
import { CommonService } from '../services/common.service';
// 获取get传值
import { ActivatedRoute } from '@angular/router';
@Component({
selector: 'app-pcontent',
templateUrl: './pcontent.page.html',
styleUrls: ['./pcontent.page.scss'],
})
export class PcontentPage implements OnInit {
public tab: any="list";
// 储存数据的变量(对象)
public list: any = {};
// 获取域名,用于图片地址
public config: any= {};
// 商品属性:数量的数据双向绑定
public num: any = 1;
constructor(public common: CommonService, public activatedRoute: ActivatedRoute) {
this.config = this.common.config;
}
ngOnInit() {
//获取get传值
this.activatedRoute.queryParams.subscribe((data: any) => {
console.log(data);
this.getProductDat(data.id);
})
}
getProductDat(id) {
var api ='api/pcontent?id=' + id;
this.common.ajaxGet(api).then((response:any) => {
console.log(response);
this.list = response.result;
})
}
// 属性选中
changeAttr(e) {
console.log(e.srcElement); // <span _ngcontent-iva-c133="">185</span>
console.log(e.srcElement.nodeName); // SPAN
if(e.srcElement.nodeName == 'SPAN') {
//获取当前点击的span DOM节点
var el = e.srcElement;
// 获取当前节点的父节点
var parent = el.parentNode;
// 获取父节点的所有子节点
var attrChildren = parent.children;
// 让所有的子节点去掉active的样式
for(var i = 0; i < attrChildren.length; i++) {
attrChildren[i].className = '';
}
// 给当前DOM节点加一个active的class
el.className = 'active';
}
}
// 增加数量
incNum() {
this.num+=1;
}
// 减少数量
decNum() {
if(this.num > 1) {
this.num-=1;
}
}
// 加入购物车
addCart() {
// 获取商品信息
var product_title = this.list['title'];
var product_id = this.list['_id'];
var product_pic = this.list['pic'];
var product_price = this.list['price'];
var product_count = this.num;
// 获取商品属性
var product_attrs: any = '';
var spanActive = document.querySelectorAll('.myAttr .active'); //获取文档中class="myAttr"里的class="active"的元素
console.log(spanActive);
for(var i = 0; i < spanActive.length; i++) {
if(i == 0) {
product_attrs += spanActive[i].innerHTML; // 第一个,直接添加
} else {
product_attrs += "-" + spanActive[i].innerHTML; // 从第二个属性开始,前面拼接一个-,属性和属性之间进行区分
}
}
var cartJson = {
product_title,
product_id,
product_pic,
product_price,
product_count,
product_attrs
}
console.log(cartJson);
}
}
上一篇: Qt 之 自定义窗口标题栏
下一篇: ORA-03113 故障排除