实例:选电影票(通过DOM对象的方法实现)

本文通过DOM对象的方法实现选电影票的功能,包括初始状态展示、选择、取消等操作。首先介绍效果展示,如初始状态的座位分布,选座后的变化。接着分析实现过程,涉及布局设计、电影票数据结构、座位可视化生成、点击响应及取消选座的逻辑。通过这个实例,读者可以加深对DOM操作的理解。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

实例:选电影票(通过DOM对象的方法实现)

效果展示

1. 初始状态

在这里插入图片描述

浅灰色的表示可以选择的座位;红色的表示票已经售出,不可选择。

2. 选择

在这里插入图片描述

点击要选择的座位,会计算出票价,并显示选择的座位对应的票。

3. 取消

通过点击绿色的座位(或者下方的票),实现取消票的选择。

分析

1. 布局

在这个例子中,布局较为简单,使用三个容器布局即可:第一个容器用来放置座位、第二个容器用来放置选择的票、第三个容器用来放置已经选择的票的总价格。

	<body>
		
		<div id="seats" class="center border">
		</div>
		
		<div id="selected" class="center border top_margin">
			
		</div>
		
		<div class="center total">
			总票价:¥<span id="totalPrice">0</span>
		</div>
	</body>

2. 电影票及电影票生成

简单分析,一张电影票最基础的信息有:id、行号、列好、价格、是否售出。(其实真正要做电影票的业务,还要包括其他的信息,例如电影名,放映事件等等。这里只是为了巩固之前学习的知识)

因此,可以写一个简单的类。

function Ticket(ticketId, rowId, colId, price, isSold){
	this.ticketId = ticketId;
	this.rowId = rowId;
	this.colId = colId;
	this.isSold = isSold;
	this.price = price;
}

接下来需要一个模拟的方法,用来生成一个场次的电影票。

function getTickets(rowNum, colNum, price){
	var tickets = {
		rowNum : rowNum,
		colNum : rowNum,
		ticketArray : new Array()
	};
	for(let i = 0; i < rowNum; ++i){
		for(let j = 0; j < colNum; ++j){
			let isSold = Math.random() > 0.8 ? true : false;//让其中一些票“售出”
			tickets.ticketArray.push(new Ticket(i * colNum + j, i + 1, j + 1, 35.5, isSold));
		}
	}
					
	return tickets;
}

3. 根据生成的电影票,生成可视化的座位


/**
 * @param tickets 模拟生成的电影票对象
 */
function buildSeats(tickets){
	//首先获取放置座位的容器
	let seats = document.getElementById("seats");
	//根据电影票的列数,生成不同的容器宽度
	//每个座位的大小(width + border + 2 * margin)
	seats.style.width = tickets.colNum * (28 + 2 + 2 * 5) + "px";
	for(let i = 0; i < tickets.rowNum; ++i){
		for(let j = 0; j < tickets.colNum; ++j){
			//创建一个“座位”元素
			let seat = document.createElement("span");
			//给这个座位添加样式,让它的class="seat"
			seat.className = "seat";
			//把这个座位对应的电影票,作为这个座位的属性,保存起来
			seat.ticket = tickets.ticketArray[i * tickets.colNum + j];
			//在一次购票过程中是否被选中,防止座位多次被选择
			seat.ticket.selected = false;
			//如果这个座位对应的票已经售出,修改它的颜色为红色
			if(seat.ticket.isSold){
				seat.style.backgroundColor = "#a55";
			}
			//绑定点击事件,在“点击座位”时触发
			seat.onclick = clickSeat;
			//将座位作为子节点插入seats,被渲染到页面中
			seats.appendChild(seat);
		}
	}
}

4. 点击座位时,触发的操作


				function clickSeat(){
					//获得这个座位对应的票
					var ticket = this.ticket;
					//如果这个票已经售出,点击这个座位不会有任何效果
					if(ticket.isSold)
						return;
					
					//接下来判断这个座位是否在被选中、
						//1. 如果未选中,则选择这张票
						//2. 如果已经选中了,则取消选择这张票
						
						
					if(!this.selected){
						//选中座位时,修改它的颜色为绿色
						this.style.backgroundColor = "#3a3";
						//将这个座位的状态修改为“已选中”
						this.selected = true;
						//获得“以选择票”容器对应的DOM对象
						var selected = document.getElementById("selected");
						//获得“总价格”容器对应的DOM对象
						var totalPrice = document.getElementById("totalPrice");
						//创建一个元素(对象),表示已经选择的票
						var selectedBtn = document.createElement("button");
						//将它与对应的座位绑定,在后续点击时,修改座位的状态
						selectedBtn.seat = this;
						//座位记录这个按钮,再次点击这个座位时,要删除这个座位
						this.selectedBtn = selectedBtn;
						//提示选择的座位的位置
						selectedBtn.innerHTML = ticket.rowId + "排" + ticket.colId + "座";
						//添加样式
						selectedBtn.className += "selected";
						//绑定点击事件(用来取消座位的选择)
						selectedBtn.onclick = cancelSelected;
						//记录对应的票
						selectedBtn.ticket = ticket;
						//渲染
						selected.appendChild(selectedBtn);
						//修改总价格
						let money = Number(totalPrice.innerHTML);
						totalPrice.innerHTML = money + ticket.price;
					}else{
						//座位已经被选中,再次点击取消选中
						this.selectedBtn.onclick();
					}
				}

5. 取消“选中”

				function cancelSelected(){
					//修改座位状态为未选中
					this.seat.selected = false;
					//修改总价格
					var totalPrice = document.getElementById("totalPrice");
					let money = Number(totalPrice.innerHTML);
					totalPrice.innerHTML = money - this.ticket.price;
					//删除结点
					this.parentNode.removeChild(this);
					//修改座位颜色
					this.seat.style.backgroundColor = "rgb(239, 239, 239)"
				}

6. 渲染

buildSeats(getTickets(20, 20, 35.5));
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值