学习javascript,实现一个简易售卖机的功能

有同学提问,说想实现一个JS售卖机的功能,我觉得这个挺有意思的,正是初学者学习JS,锻炼软件开发思维的一个好题目,所以就实现了一下,希望可以有帮助。

目录

1 需求分析

2  开发实现

2.1 商家端录入

2.2 用户端实现

3 建议改进 


1 需求分析

需求是这样子的:完成一个自动售货机,至少有3个商品,每个商品都有价格和数量,每购买一次商品,数量会减1,余额也会减少。当余额小于商品的价格时,会提示“余额不足,无法购买商品”;当数量为0如果用户继续购买时,会提示“商品已售完,无法购买”。

通过需求,我们可以分析出以下实现步骤:

商家端实现步骤

  1. 可以自主录入,录入商品名称、商品单价、商品初始数量;
  2. 录入完成后,有按钮,点击按钮保存商品;
  3. 保存商品后,需要展示自己已经录入过商品信息;
  4. 录入结束,就可以跳转到用户界面去售卖了;

用户端实现步骤 

  1. 展示商家页面录入的商品,展示为列表
  2. 列表元素,展示信息包括商品名称、商品单价、剩余数量以及购买按钮
  3. 用户默认初始余额为0,;
  4. 做简单点,这个页面可以为用户充值,并展示充值金额;
  5. 当用户购买商品时,需要判断余额大于购买商品的单价并且商品数量大于0,则用户余额减去商品单价,并且商品剩余数量减1;
  6. 当用户余额小于购买商品单价时,提示“余额不足,无法购买该商品”;
  7. 当用户购买商品数量等于0时,提示“该商品已售完,无法购买”

2  开发实现

2.1 商家端录入

因为商家端录入的数据,要和用户端跨页面通信数据,所以我们把录入的信息存入localStorage中,源码实现如下:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>商家录入</title>
<style>
    
</style>
</head>
<body>
    <p><b>商品录入</b></p>
    <div>
        <label>商品名称:</label><input type="text" id="name" />
    </div>
    <div>
        <label>商品金额:</label><input type="number" id="money" />
    </div>
    <div>
        <label>商品数量:</label><input type="number" id="number" />
    </div>
    <button onclick="enterProduct()">录入</button>
    
    <br/>
    <p><b>已录入商品展示:</b></p>
    <div id="productList"></div>
    <button onclick="go2Sell()">开始售卖</button>

    <script>
        var productList = [];
        function enterProduct() {
            var name = document.getElementById('name').value;
            var money = document.getElementById('money').value;
            var number = document.getElementById('number').value;
            var productShowDom = document.getElementById('productList');
            productList.push({
                name,
                money,
                number
            });
            localStorage.setItem('product', JSON.stringify(productList));
            // 展示已录入商品
            var proShowArr = [], proShowStr = '';
            for (var i=0;i<productList.length;i++) {
                proShowArr.push('<div>');
                proShowArr.push(`${i+1} ${productList[i]['name']} ¥${productList[i]['money']} ${productList[i]['number']}`);
                proShowArr.push('</div>');
            }
            proShowStr = proShowArr.join('');
            productShowDom.innerHTML = proShowStr;
        }
        function go2Sell() {
            if (productList.length === 0) {
                alert('请录入商品后再进行售卖');
                return;
            }
        }
    </script>
</body>
</html>

2.2 用户端实现

首先从localStorage获取数据,展示为列表,初始化展示用户余额为0;然后按钮操作逐个进行判断,源代码如下:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>用户购买</title>
<style>
    #productListBox {
        margin: 100px;
        margin-bottom: 20px;
        display: flex;
        width: 800px;
    }
    #productListBox div {
        margin-left: 50px;
        width: 200px;
        border: 1px solid #CCC;
    }
    .recharge {
        margin-left: 150px;
    }
</style>
</head>
<body>
    <div id="productListBox"></div>
    <p class="recharge">
        <input type="number" id="balanceInput" /><button onclick="rechMoney()">充值</button>
    </p>
    <p class="recharge">
        余额:¥<span id="balance"></span>
    </p>
    <script>
        var balanceDom = document.getElementById('balance');
        balanceDom.innerText = 0;

        function showProductList() {
            var productDom = document.getElementById('productListBox');
            var proData = localStorage.getItem('product');
            proData = JSON.parse(proData);
            var proShowArr = [], proShowStr = '';
            for (var i=0;i<proData.length;i++) {
                proShowArr.push('<div>');
                    proShowArr.push(`<p>${proData[i]['name']}</p>`);
                    proShowArr.push(`<p>售价:${proData[i]['money']}</p>`);
                    proShowArr.push(`<p>剩余:${proData[i]['number']}</p>`);
                    proShowArr.push(`<button onclick=buy(${i})>购买</button>`);
                proShowArr.push('</div>');
            }
            proShowStr = proShowArr.join('');
            productDom.innerHTML = proShowStr;
        }

        showProductList();

        function rechMoney() {
            var rechMoneyVal = document.getElementById('balanceInput').value;
            var balanceDom = document.getElementById('balance');
            balanceDom.innerText = rechMoneyVal;
            document.getElementById('balanceInput').value = '';
        }
        function buy(index) {
            var proData = localStorage.getItem('product');
            proData = JSON.parse(proData);
            if (Number(proData[index]['number']) <= 0) {
                alert('该商品已售完,无法购买');
                return;
            }
            var balanceDom = document.getElementById('balance');
            if (Number(balanceDom.innerText) < Number(proData[index]['money'])) {
                alert('余额不足,无法购买该商品');
                return;
            }
            var newBalance = Number(balanceDom.innerText) - Number(proData[index]['money']);
            balanceDom.innerText = newBalance;

            var productItemNum = Number(proData[index]['number']);
            productItemNum--;
            proData[index]['number'] = productItemNum;
            localStorage.setItem('product', JSON.stringify(proData));

            showProductList();
        }
    </script>
</body>
</html>

3 建议改进 

这事比较简易的实现,首先来说样式需要做的漂亮一些,要不这就真的只是一个小demo;录入的时候,录入完成一个就应该把输入框内的信息清除掉;我们这里存入了localStorage,到了真实项目开发,或者往后做,肯定是要通过接口存入数据库的,到时候就可以录入更多更多的商品了。

如果你是一名在校学生,赶紧抓紧时间学习起来吧,希望等你出来的时候,可以跑赢更多的人。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/610556.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Linux中的fork与进程地址空间

目录 前言 一、进程地址空间 二、fork的值返回 三、高清图链接 总结 前言 在博主的《进程状态解析》一文中&#xff0c;在讨论进程创建时&#xff0c;提到了一个系统调用接口fork&#xff0c;它在使用过程中表现出对于父子进程不一致的返回结果&#xff0c;而且似乎还具有…

深入学习指针2

前言 hello,我又来了&#xff0c;今天有我继续带领大家深入的学习指针&#xff0c;通过上次的学习&#xff0c;我们已经了解到了指针的基本概念&#xff0c;指针如何使用&#xff0c;指针使用的益处&#xff0c;以及一些相关的概念&#xff0c;那今天我们就继续深入的学习&am…

Docker笔记(七)使用Docker部署Spring Boot项目

本文介绍如何使用Docker打包并部署Spring Boot多模块项目。 其中本文涉及的Docker的私库是用Nexus3搭建的。 使用Docker部署Spring Boot项目有三种方式 &#xff08;1&#xff09;使用 spring-boot-maven-plugin内置的build-image. &#xff08;2&#xff09;使用 Google 的 j…

STM32CubeMX软件使用(超详细)

1、Cube启动页介绍 2、芯片选择页面介绍 3、输入自己的芯片型号&#xff0c;这里以STM32U575RIT6举例 4、芯片配置页码介绍 5、芯片外设配置栏详细说明 6、点击ClockConfiguration进行时钟树的配置&#xff0c;选择时钟树后可以选择自己想使用的时钟源&#xff0c;也可以直接输…

MySQL数据库——基础事务操作-BEGIN-COMMIT-ROLLBACK

DDL CREATE TABLE student (id int(11) NOT NULL AUTO_INCREMENT COMMENT 学号,createDate datetime DEFAULT NULL,userName varchar(20) DEFAULT NULL,pwd varchar(36) DEFAULT NULL,phone varchar(11) DEFAULT NULL,age tinyint(3) unsigned DEFAULT NULL,sex char(2) DEFAU…

MySQL企业级开发重点之事物和索引

事物 -- 解散学工部 delete from tb_dept where id 1;-- 删除部门下的员工 delete from tb_emp where dept_id 1; 介绍和操作 我们应该将两个语句写成一个语句 -- 开启事物 start transaction ;-- 解散学工部 delete from tb_dept where id 3;-- 删除部门下的员工 delete fr…

Word页脚设置“第X页共X页”的方法【域实现】

Word页脚设置“第X页共X页”的方法【域实现】 在设置Word页码格式的要求中&#xff0c;有时需要设置为“第X页共X页”这种格式&#xff0c;使用Word中的域功能可实现&#xff0c;同时&#xff0c;在某些情况下&#xff0c;可能还需要减去封面的页码&#xff0c;接下来为具体步…

传感器—超声波雷达

声波技术 在讲述超声波雷达之前&#xff0c;先了解一下声波的概念以及超声波和声波之间的关系 什么是声波&#xff1f; 声波是物体机械振动状态&#xff08;或能量&#xff09;的传播形式。所谓振动是指物质的质点在其平衡位置附近进行的往返运动形式&#xff0c;这种振动状…

JAVA文件的简单操作

文件IO&#xff08;Input和Output&#xff09; 文件的输入和输出是人为规定的&#xff0c;那么什么是输入&#xff1f;什么是输出捏&#xff1f;在这里统一已CPU为基准 例如&#xff1a;将文件由内存写入硬盘就是输出&#xff0c;有硬盘写入内存就是输入。可以总结为&#xff…

C语言—深入理解指针(3)

1.字符指针变量 一般使用&#xff1a; 另一种使用方法&#xff1a; “hello world”是一个常量字符串&#xff0c;不能被修改。 上述代码是将字符串中的首字符‘h’赋值给指针pstr&#xff0c;用%s打印字符串的时候&#xff0c;只需要提供首字符的地址就行。&#xff08;如果…

LoadRunner性能测试基本步骤

前言 本文旨在指导初学者使用LoadRunner进行基础的性能测试。 我们在接到一个性能测试任务的时候&#xff0c;需要从以下几点考虑&#xff1a;我们的测试对象是什么&#xff0c;测试要求是什么&#xff0c;测试环境怎么部署的&#xff0c;业务规模如何&#xff0c;哪些业务点是…

这是一关于DSC相关的文档

这是一关于DSC相关的文档 上面这幅图清晰的展示了somewhat flat的像素图示

CRMEB 开源/标准版商城系统客服配置教程

管理后台/设置/系统设置/商城配置/客服端配置 有系统客服/拨打电话/跳转链接可选&#xff0c;系统客服为系统自带的客服系统&#xff0c;拨打电话为用户点击联系客服为拨打客服电话的方式&#xff0c;跳转链接为可以跳转自己开发的客服系统或者第三方的客服系统或者企业微信的…

etcd单机部署和集群部署

1、etcd单实例部署 对于平常的学习&#xff0c;其实搭建一个单机节点是够了的。接下来就讲讲怎么搭建单机节点。 本次部署是在 centos7 系统&#xff0c;cpu 为amd64 上面进行的。 部署是直接使用官方编译好的二进制文件&#xff0c;大家也可以直接看 ectd-releases 界面选择…

开源交互审计系统:功能强大、安全好用【送源码】

在当今信息化时代&#xff0c;网络安全越来越受到重视。传统的远程控制工具&#xff0c;如RDP、SSH、VNC等&#xff0c;虽然方便易用&#xff0c;但存在安全隐患&#xff0c;容易被黑客利用。很多时候我们都需要做一些防护的处理来来保障网络安全。 今天了不起来分享一款开源好…

OSPF链路状态数据库

原理概述 OSPF是一种基于链路状态的动态路由协议&#xff0c;每台OSPF路由器都会生成相关的LSA&#xff0c;并将这些LSA通告出去。路由器收到LSA后&#xff0c;会将它们存放在链路状态数据库LSDB中。 LSA有多种不同的类型&#xff0c;不同类型的LSA的功能和作用是不同的&…

LearnOpenGL(十一)之光源

一、投光物 将光投射(Cast)到物体的光源叫做投光物(Light Caster)。 二、平行光 当一个光源处于很远的地方时&#xff0c;来自光源的每条光线就会近似于互相平行&#xff0c;我们可以称这些光为平行光。当我们使用一个假设光源处于无限远处的模型时&#xff0c;它就被称为定向…

django显示网页步骤

显示网页步骤 小白的django学习笔记 2024/5/6 8:30 文章目录 显示网页步骤创建输入框&#xff08;文本、单选、多选&#xff09;效果如何在django中显示网页写函数配置地址运行&#xff0c;要选择这个工程名的&#xff0c;使用socket复制ip&#xff0c;后面在加上名字,成功&…

Final Draft 12 for Mac:高效专业剧本创作软件

对于剧本创作者来说&#xff0c;一款高效、专业的写作工具是不可或缺的。Final Draft 12 for Mac就是这样一款完美的选择。这款专为Mac用户设计的剧本创作软件&#xff0c;凭借其卓越的性能和丰富的功能&#xff0c;让您的剧本创作更加得心应手。 Final Draft 12支持多种剧本格…

react+antd --- 日期选择器,动态生成日期表格表头

先看一下效果---有当前月的日期 技术: 1: react 2:antd-UI库 -- table 3:moment--时间处理库 代码效果: import { Button, DatePicker, Table } from antd; import { useEffect, useState } from react; import moment from moment;function Club() {const [selecte…
最新文章