javascript 练习 写一个简单 另类录入 电脑组装报价表 可打印

数据格式

(1代表cpu、2代表主板、3代表内存、。。。)

1@i3 12100 @630
2@H610 @480
3@DDR4 3200 16G @220
4@500G M.2  @299
5@300W电源 @150
6@小机箱 @85
7@GT 730G 4G @350
8@WD 2T @399
9@飞利浦 24Led @580

 主代码 Html + JS

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta http-equiv="X-UA-Compatible" content="ie=edge" /><title>电脑组装报价表</title><link rel="stylesheet" href="./iconfont/iconfont.css"><link rel="stylesheet" href="css/index.css" />
</head><body><h1>电脑组装报价表</h1><form class="info no-print" autocomplete="off"><textarea placeholder="请输入内容" class="uname" name="uname" lay-verify="required" style="width: 500px;height: 100px;"></textarea><button class="add"><i class="iconfont icon-tianjia"></i>录入</button></form><div class="title no-print">共有数据<span>0</span>条</div><table><thead><tr><th>ID</th><th>类别</th><th>配件名称</th><th>数量</th><th>单价</th><th>金额</th><th>录入时间</th><th>操作</th></tr></thead><tbody><!-- 表格内容 --></tbody></table><div class="title heji">大写: <strong>零</strong>&nbsp;&nbsp;&nbsp;    合计:<span>0</span>元</div><div class="boot"><button class="printer no-print"><i class="iconfont icon-tianjia"></i>打印</button></div><script src="js/daxie.js"></script><script>// 参考数据const initData = [{stuId: 1,bname: 'cpu',goods: 'i3 12100',sl: 1,dj: 630,je: 630,time: '2099/9/9 08:08:08'}]// 1. 渲染业务// 1.1 先读取本地存储的数据// (1). 本地存储有数据则记得转换为对象然后存储到变量里面,后期用于渲染页面// (2). 如果没有数据,则用 空数组来代替let count = 0 //合计数据const arr = JSON.parse(localStorage.getItem('data')) || []console.log('数据arr:',arr)// 1.2 利用map和join方法来渲染页面const tbody = document.querySelector('tbody')function render() {// (1). 利用map遍历数组,返回对应tr的数组const trArr = arr.map(function (ele, index) {count +=parseInt(ele.dj)return `<tr><td>${ele.stuId}</td><td>${ele.bname}</td><td>${ele.goods}</td><td>${ele.sl}</td><td>${ele.dj}</td><td>${ele.je}</td><td>${ele.time}</td><td><a href="javascript:" data-id="${index}"><i class="iconfont icon-shanchu"></i>删除</a></td></tr>`count +=ele.dj // 合计储存数据})console.log(trArr)// (2). 把数组转换为字符串 join// (3). 把生成的字符串追加给tbody tbody.innerHTML = trArr.join('')// 显示共计有几条数据document.querySelector('.title span').innerHTML = arr.length}render()// 2. 新增业务const info = document.querySelector('.info')const uname = document.querySelector('.uname')// 2.1 form表单注册提交事件,阻止默认行为info.addEventListener('submit', function (e) {e.preventDefault()// 2.2 非空判断if (!uname.value) {return alert('输入内容不能为空')}const dataT = [] // 接收新的数据对像let lines = uname.value.split("\n");console.log(lines)// console.log(typeof(lines))// 2.3 给 arr 数组追加对象,里面存储 表单获取过来的数据for (let line of lines) {let parts = line.split("@"); // 将每行分割成组件编号、名称和价格console.log(parts)let [number, name, price] = parts;price = price.trim(); // 去除价格两侧的空格// 根据组件编号创建对象,并添加到结果数组中if (number === "1") {dataT.push({ id: "1", lx: "cpu", pj: name, jg: price });} else if (number === "2") {dataT.push({ id: "2", lx: "主板", pj: name, jg: price });} else if (number === "3") {dataT.push({ id: "3", lx: "内存", pj: name, jg: price });} else if (number === "4") {dataT.push({ id: "4", lx: "固态硬盘", pj: name, jg: price });} else if (number === "5") {dataT.push({ id: "5", lx: "电源", pj: name, jg: price });} else if (number === "6") {dataT.push({ id: "6", lx: "机箱", pj: name, jg: price });} else if (number === "7") {dataT.push({ id: "7", lx: "外置显卡", pj: name, jg: price });} else if (number === "8") {dataT.push({ id: "8", lx: "机械硬盘", pj: name, jg: price });} else if (number === "9") {dataT.push({ id: "9", lx: "显示器", pj: name, jg: price });}}for (let i = 0; i < dataT.length; i++){     arr.push({// 处理 stuId:数组最后一条数据的stuId + 1      stuId: arr.length ? arr[arr.length - 1].stuId + 1 : 1,bname: dataT[i].lx,goods: dataT[i].pj,sl: 1,dj: dataT[i].jg,je: dataT[i].jg,time: new Date().toLocaleString()})// 2.4 渲染页面和重置表单(reset()方法)render()}this.reset() // 重置表单// 2.5 把数组重新存入本地存储里面,记得转换为JSON字符串存储localStorage.setItem('data', JSON.stringify(arr))location.reload(); // 刷新显示储存数据 合计结果})// 3. 删除业务// 3.1 采用事件委托形式,给 tbody 注册点击事件tbody.addEventListener('click', function (e) {// 判断是否点击的是删除按钮  A 链接if (e.target.tagName === 'A') {// alert(11)// 3.2 得到当前点击链接的索引号。渲染数据的时候,动态给a链接添加自定义属性例如 data-id="0"console.log(e.target.dataset.id)// 确认框 确认是否要真的删除if (confirm('您确定要删除这条数据吗?')) {// 3.3 根据索引号,利用 splice 删除数组这条数据arr.splice(e.target.dataset.id, 1)// 3.4 重新渲染页面 render()// 3.5 把最新 arr 数组存入本地存储localStorage.setItem('data', JSON.stringify(arr))location.reload(); // 刷新显示储存数据 合计结果}}})// 显示小写合计console.log('数量:',count)document.querySelector('.heji span').innerHTML = count// 显示大写合计,用numberTochinese 函数转成大写let Num = numberToChinese(count)document.querySelector('.heji strong').innerHTML = Num
// 打印function printPage() {window.print();}// 监听打印按钮const pr = document.querySelector('.printer')pr.addEventListener('click',function(){printPage();})</script>
</body></html>

注1:其中数据转换:

let parts = line.split("@"); // 将每行分割成组件编号、名称和价格

// 根据组件编号创建对象,并添加到结果数组中

                    if (number === "1") {

                        dataT.push({ id: "1", lx: "cpu", pj: name, jg: price });

                    } else if (number === "2") {

                        dataT.push({ id: "2", lx: "主板", pj: name, jg: price });

                    } else if (number === "3") {

                        dataT.push({ id: "3", lx: "内存", pj: name, jg: price });

                    } else if (number === "4") {

                        dataT.push({ id: "4", lx: "固态硬盘", pj: name, jg: price });

                    } else if (number === "5") {

                        dataT.push({ id: "5", lx: "电源", pj: name, jg: price });

                    } else if (number === "6") {

                        dataT.push({ id: "6", lx: "机箱", pj: name, jg: price });

                    } else if (number === "7") {

                        dataT.push({ id: "7", lx: "外置显卡", pj: name, jg: price });

                    } else if (number === "8") {

                        dataT.push({ id: "8", lx: "机械硬盘", pj: name, jg: price });

                    } else if (number === "9") {

                        dataT.push({ id: "9", lx: "显示器", pj: name, jg: price });

                    }

注2:两条内存 未解决 可以当 双条 合成 1套  

注3:打印 只是用CSS 隐藏 不打印的

CSS代码 index.css

* {margin: 0;padding: 0;
}a {text-decoration: none;color: #721c24;
}h1 {text-align: center;color: #333;margin: 20px 0;}.title {width: 933px;height: 50px;line-height: 50px;padding-right: 15px;border: 1px solid #ebebeb;margin: 10px auto;background-color: #f2f2f2;text-align: right;
}.title span {display: inline-block;vertical-align: middle;height: 20px;margin: -3px 5px 0;text-align: center;line-height: 20px;color: #f26934;font-weight: 700;
}table {margin: 0 auto;width: 950px;border-collapse: collapse;color: #3c3637;
}th {padding: 10px;background: #f2f2f2;font-size: 18px;text-align: left;
}td,
th {border: 1px solid #bbbaba;padding: 15px;
}td {color: #080808;font-size: 16px;}tbody tr {background: #fff;
}tbody tr:hover {background: #fbfafa;
}tbody a {display: inline-block;width: 80px;height: 30px;text-align: center;line-height: 30px;color: #fff;background-color: #f26934;
}.info {width: 900px;margin: 50px auto;text-align: center;
}.info input,
.info select {width: 100px;height: 30px;outline: none;border: 1px solid #ebebeb;padding-left: 5px;box-sizing: border-box;margin-right: 10px;
}.info button {width: 70px;height: 30px;background-color: #5dbfd8;outline: none;border: 0;color: #fff;cursor: pointer;font-size: 14px;
}.info button:hover {background-color: #52abc1;
}.printer {width: 70px;height: 30px;background-color: #5dbfd8;outline: none;border: 0;color: #fff;cursor: pointer;font-size: 14px;
}.printer:hover {background-color: #52abc1;
}.boot {margin: 0 auto;width: 950px;padding-bottom: 20px;text-align: center;
}/* 对打印机进行样式设置 */
@media print {.no-print {display: none; /* 在打印时隐藏带有no-print类的元素 */}td,th {border: 1px solid #1a1a1a;padding: 15px;}
}@media print {@page {margin-top: 0;margin-bottom: 0;}header, footer {display: none;}
}

小写转大写 JS代码 daxie.js

function numberToChinese(num) {const digit = {0: '零',1: '壹',2: '贰',3: '叁',4: '肆',5: '伍',6: '陆',7: '柒',8: '捌',9: '玖',};const unit = ['', '拾', '佰', '仟', '万', '亿'];const moneyStr = String(num.toFixed(2));const moneyArr = moneyStr.split('.');const integralPart = Number(moneyArr[0]);const decimalPart = Number(moneyArr[1]);const toChinese = (num) => {const numArr = String(num).split('');const len = numArr.length;const resultArr = [];for (let i = 0; i < len; i++) {const digitIndex = Number(numArr[i]);if (i !== len - 1 && digitIndex !== 0) {resultArr.push(digit[digitIndex], unit[len - i - 1]);} else {resultArr.push(digit[digitIndex]);}}return resultArr.join('');};if (num === 0) {return '零元整';}const result = toChinese(integralPart);if (decimalPart === 0) {return result + '元整';} else {return result + '元' + toChinese(decimalPart) + '角';}}console.log(numberToChinese(123456789.12)); // 壹亿贰仟叁佰肆拾伍万陆仟柒佰捌拾玖元壹角贰分

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Linux zImage image是什么

2024年5月4日&#xff0c;周六下午 Linux zImage是Linux内核的一种压缩格式。在Linux系统中&#xff0c;内核通常以zImage格式存储在启动介质&#xff08;如硬盘、闪存等&#xff09;上&#xff0c;并由引导加载程序加载到内存中执行。 zImage是一种压缩的内核映像格式&#x…

Python学习笔记------pycharts模块

pyecharts模块简介 Echarts是个由百度开源的数据可视化&#xff0c;凭借着良好的交互性&#xff0c;精巧的图表设计&#xff0c;得到众多开发者的认可&#xff0c;而python是门富有表达力的语言&#xff0c;很适合用于数据处理&#xff0c;当数据分析遇上数据可视化时pyechart…

EPAI手绘建模APP演示板、材质编辑器、样式编辑器

(11) 更多 图 74 更多工具栏 ① 演示板&#xff1a;打开关闭演示板。演示板用来显示从设备导入的模型图纸图片或者打开模型建模教程网页&#xff0c;是建模过程中一个辅助功能。有些设备有小窗口功能有些没有&#xff0c;对于没有小窗口功能的设备&#xff0c;通过演示板能够在…

LeetCode--质数

Q: 输出 100 以内所有质数 1.0 /* 第一层循环控制检查到哪个数* 第二层通过遍历除以每个比他小的数的方式,检查每个数是不是质数* 由于要遍历检查,设置一个标记,只要任意一次循环可以整除,我们就设置该标记为不是质数 */boolean isPrime true;for (int i 2; i < 100; i)…

Boosting算法揭秘:从原理到scikit-learn实战

Boosting算法揭秘&#xff1a;从原理到scikit-learn实战 在机器学习的江湖中&#xff0c;Boosting算法以其强大的预测能力和独特的训练方式占据了一席之地。与Bagging算法并行训练的理念不同&#xff0c;Boosting算法更注重模型的串行迭代和错误修正。本文将从Boosting算法的基…

一键自动化博客发布工具,chrome和firfox详细配置

blog-auto-publishing-tools博客自动发布工具现在已经可以同时支持chrome和firefox了。 很多小伙伴可能对于如何进行配置和启动不是很了解&#xff0c;今天带给大家一个详细的保姆教程&#xff0c;只需要跟着我的步骤一步来就可以无障碍启动了。 前提条件 前提条件当然是先下…

ios app 之 中国大陆 ICP备案问题

从2024年3月份起&#xff0c;上传到苹果商店&#xff08;app store connect&#xff09;中的app, 若使用地区中选择了 亚太地区 - 中国大陆&#xff0c; 则需要上传 中国大陆 app 的ICP备案&#xff0c;下面是对本人对备案的实操及理解&#xff1a; 1) ICP备案与 app store co…

设计模式——行为型模式——策略模式

策略模式 定义 策略模式定义了一系列算法&#xff0c;并将每个算法封装起来&#xff0c;使它们可以相互替换&#xff0c;且算法的变化不会影响使用算法的客户。 策略模式属于对象行为模式&#xff0c;它通过对算法进行封装&#xff0c;把使用算法的责任和算法的实现分割开来&a…

uniapp+vue基于移动端的药品进销存系统r275i

最后我们通过需求分析、测试调整&#xff0c;与药品进销存管理系统管理系统的实际需求相结合&#xff0c;设计实现了药品进销存管理系统管理系统。 系统功能需求包含业务需求、功能需求用户需求&#xff0c;系统功能需求分析是在了解用户习惯、开发人员技术和实力等各个因素的前…

【Conda】解决无名虚拟环境问题

文章目录 问题描述&#xff1a;无名虚拟环境解决步骤1 添加虚拟环境目录到envs步骤2 成功命名 问题描述&#xff1a;无名虚拟环境 如果不指定创建目录&#xff0c;默认创建在C盘用户目录下&#xff0c;这应该是很多人不愿意的吧。 指定目录创建虚拟环境命令如下&#xff1a; …

【微服务】——Docker 基础知识

这里写自定义目录标题 1.1 了解Docker1.1.1应用部署的环境问题1.1.2.Docker解决依赖兼容问题1.1.3.Docker解决操作系统环境差异1.1.4.小结 1.2.Docker和虚拟机的区别1.3.Docker架构1.3.1.镜像和容器1.3.2.DockerHub1.3.3.Docker架构1.3.4.小结 1.4.安装Docker——未实践 2.Dock…

探索CSS3文本效果:打造魅力无限的网页排版

CSS3为网页设计带来了革命性的变化&#xff0c;特别是在文本效果方面&#xff0c;它赋予了开发者前所未有的创意空间。本文将带你深入了解CSS3中一些令人兴奋的文本效果&#xff0c;从基本的阴影处理到复杂的动画效果&#xff0c;每个技巧都将通过实际代码示例展现其魅力所在。…

【Linux】`cat` 命令详解:查看、合并文件的利器

我把我唱给你听 把你纯真无邪的笑容给我吧 我们应该有快乐的 幸福的晴朗的时光 我把我唱给你听 用我炙热的感情感动你好吗 岁月是值得怀念的留恋的 害羞的红色脸庞 谁能够代替你呀 趁年轻尽情的爱吧 最最亲爱的人啊 路途遥远我们在一起吧 &#x1f3b5; 叶…

使用Python和Pygame创建一个简单的飞机大战游戏 [附源码]

在这个数字化时代&#xff0c;游戏已经成为我们生活中不可或缺的一部分。从经典的街机游戏到现代的3D游戏&#xff0c;游戏行业经历了巨大的变革。然而&#xff0c;有时候&#xff0c;简单的游戏反而能够带来更多的乐趣和满足感。在本篇文章中&#xff0c;我们将使用Python和Py…

Vue 组件间的数据绑定

在Vue组件中&#xff0c;v-model指令可以用来实现双向数据绑定。它用于将组件的属性和父组件中的数据进行双向绑定&#xff0c;使得当属性的值改变时&#xff0c;父组件中的数据也会相应地改变&#xff0c;并且当父组件中的数据改变时&#xff0c;属性的值也会相应地改变。 目…

c++ 使用libuv库

一、克隆libuv源码 打开命令行或终端。使用git clone命令克隆libuv的源码仓库。例如&#xff1a; git clone https://github.com/libuv/libuv.git 这将在当前目录下创建一个名为libuv的目录&#xff0c;其中包含libuv的源码。 二、编译安装libuv 进入libuv的源码目录&#x…

掌握算法艺术

学习算法是计算机科学领域的一个重要分支&#xff0c;它对提高编程能力、解决复杂问题以及参与竞争激烈的技术面试都非常关键。 概要&#xff1a; 1. 引言&#xff1a;为什么学习算法很重要&#xff1f; - 解释算法在计算机科学中的作用 - 讨论算法知识对于技术面试和职…

多级留言/评论的功能实现——SpringBoot3后端篇

目录 功能描述数据库表设计后端接口设计实体类entity 完整实体类dto 封装请求数据dto 封装分页请求数据vo 请求返回数据 Controller控制层Service层接口实现类 Mapper层Mybatis 操作数据库 补充&#xff1a;返回的数据结构自动创建实体类 最近毕设做完了&#xff0c;开始来梳理…

github.com/gin-contrib/timeout应前置使用

首先&#xff0c;gin的中间件是有执行顺序的&#xff0c;就是按照添加的顺序进行的。之前没在意&#xff0c;我把timeout中间件放在了最后面&#xff0c;导致业务一直不正常&#xff0c;后面debug源码总算看明白了&#xff1a; 源码入口&#xff1a; func(c *gin.Context) {fi…

WPF应用程序XAML

当WPF应用程序创建好后&#xff0c;系统会自动添加一个Grid控件到窗体上&#xff0c;通过Grid控件能够方便地对界面进行布局.下面代码中为Grid控件添加了两行两列&#xff0c;分别用RowDefinitions属性ColumnDefinitions属性表示行的集合和列的集合&#xff0c;集合中有RowDefi…