房屋水电费记账本:内置的数组数据击按钮不能删除,页面手动添加的可以删除

html 复制代码
<!DOCTYPE html>
<html lang="zh-CN">
	<head>
		<meta charset="UTF-8">
		<meta name="viewport" content="width=device-width, initial-scale=1.0">
		<title>房租水电费记录</title>
		<script type="text/javascript">
			document.addEventListener('plusready', function() {
				//console.log("所有plus api都应该在此事件发生后调用,否则会出现plus is undefined。")
			});
		</script>
		<style>
			* {
				margin: 0;
				padding: 0;
				box-sizing: border-box;
			}

			body {
				background-color: #0a1f19;
				color: #ffffff;
				text-shadow: 1px 1px 1px #000000;
				text-align: center;
			}

			/* 凹背景样式 */
			.total-cost b,
			.common-span {
				color: #ffff00;
				position: relative;
				border-radius: 3px;
				font-size: 30px;
				padding: 0 5px;
				font-weight: bold;
				box-shadow: inset -2px -2px 3px rgba(255, 255, 255, 0.589), inset 2px 2px 3px rgba(0, 0, 0, 0.6);
			}

			.total-cost b::before,
			.common-span::before {
				content: "";
				background: linear-gradient(white, transparent 3%) 50% 50%/97% 97%,
					linear-gradient(rgba(255, 255, 255, 0.5), transparent 50%, transparent 80%, rgba(255, 255, 255, 0.5)) 50% 50%/97% 97%;
				width: 100%;
				height: 100%;
				position: absolute;
				top: 0;
				left: 0;
				border-radius: 5px;
				transform: scale(0.9);
			}

			.common-h2 {
				background-color: #28a7462e;
				border-radius: 0 0 2px 2px;
			}

			/* 日期行 */
			.table-body {
				display: flex;
				flex-direction: column-reverse;
				border: 2px solid #ffc;
				border-radius: 3px;
			}

			.date-month {
				box-shadow: 0 0 10px 2px rgba(0, 0, 0, 0.2), 0 0 1px 2px black,
					inset 0 2px 2px -2px white, inset 0 0 2px 9px #47434c,
					inset 0 0 2px 10px #ff0000;
				display: flex;
				flex-direction: column-reverse;
				padding: 10px;
				margin: 3px;
				border-radius: 3px;
					border: 2px solid #ffaa7f;
			}

			.details,
			.rent-row {
				width: 100%;
				display: flex;
				justify-content: space-around;
				background-color: #28a745;
				border-radius: 5px 5px 0 0;
				border: 5px solid #333333;
			}

			.date-column {
				display: flex;
				justify-content: space-around;
				align-items: center;
				/* margin-top: 12px; */
				width: 100%;
				margin: 0 auto;
				background-color: #144756;
			}

			/*日期标题 */
			.date {
				transform: translate(-12%, -236%) scale(0.8);
			}

			.year {
				position: relative;
				top: 35px;
				left: 6px;
				padding: 15px 16px 25px 12px;
				border-radius: 10px 10px 0 0;
				color: rgb(234, 255, 0);
				background-color: #ff0000;
			}

			.recordCheckbox {
				position: relative;
				transform: translate(90%, 230%) scale(2);
				z-index: 999999;
			}

			h1 {
				position: absolute;
				border: 5px solid #333;
				width: 135px;
				line-height: 115px;
				font-size: 60px;
				letter-spacing: -3px;
				-webkit-text-fill-color: transparent;
				border-radius: 20px 10px 10px 10px;
				box-shadow: inset 4px 4px 4px rgba(255, 255, 255, 0.6), inset -4px -4px 5px rgba(0, 0, 0, 0.6);
			}

			.month1 {
				clip-path: polygon(0% 0%, 100% 0%, 100% 50%, 0% 50%);
				text-shadow: 1px 1px 1px #d1ec04;
				-webkit-text-stroke: #fffbfb 1px;
			}

			.month2 {
				clip-path: polygon(0% 50%, 100% 50%, 100% 100%, 0% 100%);
				transform: translateY(1px);
				z-index: 20;
				text-shadow: 1px 1px 1px #ff0303;
				-webkit-text-stroke: #ffffff 1px;
			}

			/*日期标题 结束*/
			/* 水表 */
			.water-meter {
				width: 90px;
				height: 90px;
				margin: 0 10px;
				border-radius: 75px;
				background: #e0f7fa;
				border: 5px solid #0288d1;
				position: relative;
				box-shadow: 0 0 10px rgba(0, 0, 0, 0.5);
			}

			.water-meter h2 {
				background: linear-gradient(to top, #0091ea, #00bcd4);
				border-radius: 0 0 75px 75px;
			}

			/* 水表 结束*/
			/* 电表 */
			.electric-meter {
				border: 5px solid #333;
				border-radius: 10px;
				background: #fff;
				box-shadow: 0 0 10px rgba(0, 0, 0, 0.5);
			}

			.electric-meter h2 {
				background-color: #28a745;
				border-radius: 0 0 2px 2px;
			}

			/* 电表结束 */
			.water-meter p {
				animation: backgroundChange2 10s infinite;
				margin: 4px;
				font-size: 25px;
				font-weight: bold;
				padding: 0 7px 3px 5px;
			}

			.electric-meter p {
				animation: backgroundChange 10s infinite;
				margin: 4px;
				font-size: 25px;
				font-weight: bold;
				padding: 0 7px 3px 5px;
			}

			@keyframes backgroundChange2 {

				0%,
				10%,
				20%,
				30%,
				40%,
				50%,
				60%,
				70%,
				80%,
				90%,
				100% {
					box-shadow: 0 0 10px 2px rgba(0, 0, 0, 0.2), 0 0 1px 2px black,
						inset 0 2px 2px -2px white, inset 0 0 2px 7px #47434c,
						inset 0 0 2px 22px #ff0000;
					color: #cfd601;
					border-radius: 33px 33px 0 0;
				}

				5%,
				15%,
				25%,
				35%,
				45%,
				55%,
				65%,
				75%,
				85%,
				95% {
					box-shadow: 0 0 10px 2px rgba(0, 0, 0, 0.2), 0 0 1px 2px black,
						inset 0 2px 2px -2px white, inset 0 0 2px 7px #47434c,
						inset 0 0 2px 22px #f6ff00;
					color: #ffffff;
					border-radius: 30px 30px 0 0;
				}
			}

			@keyframes backgroundChange {

				0%,
				10%,
				20%,
				30%,
				40%,
				50%,
				60%,
				70%,
				80%,
				90%,
				100% {
					box-shadow: 0 0 10px 2px rgba(0, 0, 0, 0.2), 0 0 1px 2px black,
						inset 0 2px 2px -2px white, inset 0 0 2px 7px #47434c,
						inset 0 0 2px 22px #ff0000;
					color: #cfd601;
					border-radius: 2px;
				}

				5%,
				15%,
				25%,
				35%,
				45%,
				55%,
				65%,
				75%,
				85%,
				95% {
					box-shadow: 0 0 10px 2px rgba(0, 0, 0, 0.2), 0 0 1px 2px black,
						inset 0 2px 2px -2px white, inset 0 0 2px 7px #47434c,
						inset 0 0 2px 22px #f6ff00;
					color: #ffffff;
					border-radius: 3px;
				}
			}

			summary {
				color: #f6ff00;
			}

			summary::marker {
				color: red;
				/* 设置箭头颜色为红色 */
			}

			.details table {
				width: 100%;
				text-align: center;
			}

			.details td {
				border: 2px solid #000000;
				background-color: #144756;
			}

			/* 房租 */
			/* 总金额 */
			.rent,
			.total-amount {
				background: #0288d1;
				margin: 10px 0;
				padding: 0 5px;
				box-shadow: inset -2px -2px 3px rgba(255, 255, 255, 0.589), inset 2px 2px 3px rgba(0, 0, 0, 0.6);
			}

			.total-amount {
				background: #f30000;
			}

			.total-cost {
				background-color: #248aa6;
			}

			/* 删除按钮样式 */
			#deleteButton {
				background-color: red;
				/* 背景颜色 */
				color: white;
				/* 字体颜色 */
				border: none;
				/* 无边框 */
				padding: 0px 5px;
				/* 内边距 */
				border-radius: 2px;
				/* 圆角 */
				cursor: pointer;
				/* 鼠标指针样式 */
				font-size: 16px;
				/* 字体大小 */
				margin-left: 10px;
				/* 左侧外边距 */
			}

			#deleteButton:hover {
				background-color: darkred;
				/* 悬停时的背景颜色 */
			}

			/* 添加按钮样式 */
			#addButton {
				background-color: green;
				/* 背景颜色 */
				color: white;
				/* 字体颜色 */
				border: none;
				/* 无边框 */
				padding: 0px 5px;
				/* 内边距 */
				border-radius: 2px;
				/* 圆角 */
				cursor: pointer;
				/* 鼠标指针样式 */
				font-size: 16px;
				/* 字体大小 */
			}

			#addButton:hover {
				background-color: darkgreen;
				/* 悬停时的背景颜色 */
			}

			.input-length {
				/* 最小宽度 */
				min-width: 30px;
			}
		</style>
	</head>
	<body>
		<h2>房租水电费记账本<button id="deleteButton">选中月上的框删除</button></h2>
		<div class="header">
			<div id="dataTable" class="table">
				<div class="input-section">
					<label> <input type="month" id="dateInput"></label>
					<label> <input type="text" id="rentInput" class="input-length" oninput="adjustWidth(this)"
							placeholder="房租"></label>
					<label><input type="text" id="waterInput" class="input-length" oninput="adjustWidth(this)"
							placeholder="水表"></label>
					<label><input type="text" id="electricInput" class="input-length" oninput="adjustWidth(this)"
							placeholder="电表"></label>
					<label> <input type="text" id="noteInput" class="input-length" oninput="adjustWidth(this)"
							placeholder="备注"></label>
					<button id="addButton" style="cursor: pointer;">添加</button>
				</div>
				<div class="table-body"> </div>
				<div class="table-footer">
					<div class="footer-cell" colspan="2">到底了,没有更多了!</div>
				</div>
			</div>
	</body>
	<script>
		let rentRecords = initRentRecords(); // 只初始化一次
		let totalWaterUsage = 0; // 总用水量
		let totalElectricityUsage = 0; // 总用电量
		function initRentRecords() {
			const storedRecords = localStorage.getItem('房租记录');
			return storedRecords ? JSON.parse(storedRecords) : [
				// 默认数据
				{
					"日期": "2024年7月25日",
					"房租": 1000,
					"水表": 66,
					"电表": 2316,
					"备注": "房租500元,押金100元",
					"禁止删除": true
				},
				{
					"日期": "2024年8月25日",
					"房租": 1500,
					"水表": 68,
					"电表": 2537,
					"备注": "3个月房租,8月25日-11月25日",
					"禁止删除": true
				},
				{
					"日期": "2024年9月25日",
					"房租": 0,
					"水表": 71,
					"电表": 2600,
					"备注": "9月30日抄表数",
					"禁止删除": true
				},
			];
		}
		// 计算函数
		function calcCosts(curr, prev) {
			const waterUsage = prev ? curr.水表 - prev.水表 : 0;
			const electricityUsage = prev ? curr.电表 - prev.电表 : 0;
			const waterFee = waterUsage > 0 ? waterUsage * 5 : 0; // 水费计算
			const electricityFee = electricityUsage > 0 ? electricityUsage * 1 : 0; // 电费计算
			const total = curr.房租 + waterFee + electricityFee; // 本月总金额计算
			// 更新总用水量和总用电量
			totalWaterUsage += waterUsage;
			totalElectricityUsage += electricityUsage;
			return {
				waterUsage,
				electricityUsage,
				waterFee,
				electricityFee,
				total,
				totalWaterUsage, // 返回总用水量
				totalElectricityUsage, // 返回总用电量
				waterUsageCalc: `${curr.水表} - ${prev ? prev.水表 : curr.水表} = ${waterUsage} (吨)`,
				electricityUsageCalc: `${curr.电表} - ${prev ? prev.电表 : curr.电表} = ${electricityUsage} (度)`,
				waterFeeCalc: `${waterUsage} * 5 = ${waterFee}(元)`,
				electricityFeeCalc: `${electricityUsage} * 1 = ${electricityFee}(元)`,
				totalCalc: `${curr.房租} + ${waterFee} + ${electricityFee} = ${total}(元)`,
			};
		}
		// 渲染数据函数
		function renderData() {
			let totalRent = 0,
				totalWaterFee = 0,
				totalElectricityFee = 0;
			const contentArea = document.getElementById('dataTable').querySelector('.table-body');
			let content = ''; // 用于存储所有内容
			rentRecords.forEach((record, index) => {
				totalRent += record.房租;
				const prevRecord = index > 0 ? rentRecords[index - 1] : null;
				const {
					waterUsage,
					electricityUsage,
					waterFee,
					electricityFee,
					total,
					waterUsageCalc,
					electricityUsageCalc,
					waterFeeCalc,
					electricityFeeCalc,
					totalCalc
				} = calcCosts(record, prevRecord);
				totalWaterFee += waterFee;
				totalElectricityFee += electricityFee;
				const month = String(parseInt(record.日期.substring(5, 7), 10)).padStart(2, '0');
				// 拼接每一项数据到 content,添加复选框
				content += `
            <div class="date-month">
                <div class="rent-row">
                    <div >房租:
                    <b class="rent">${record.房租}元</b></div>
                    <div >本月已缴总金额:
                    <b class="total-amount">${total}元</b></div>
                </div>
                <div class="date-column">
                    <div class="date">
                        <div class="year-month">
                            <sub class="year">${record.日期.substring(0, 5)}</sub>  
                            <input type="checkbox" class="recordCheckbox" data-index="${index}" />
                            <h1 class="month1">${month}月</h1>
                        </div>
                        <h1 class="month2">${month}月</h1>
                    </div>
                    <div class="water-meter">
                        <p>${record.水表}</p>
                        <h2>水表</h2>
                    </div>
                    <div class="electric-meter">
                        <p>${record.电表}</p>
                        <h2>电表</h2>
                    </div>
                </div>
                <details class="details">
                    <summary>
                        查看详细信息
                    </summary>
                    <div>
                    <p><span>首月押金500元</span><span>房租500元/月</span></p>
                       <p><span>水:5元/吨</span><span>电:1元/度</span></p> 
             </div>
             <table class="details-table">
                 <tr >
                <td>
                    <div class="rent common-div-left">
                        <p>500元/月</p>
                        <span class="common-span">${record.房租}元</span>
                        <h2 class="common-h2">房租</h2>
                    </div>
                </td>
                <td>
                    <div class="total-amount common-div-right">
                        <p>${totalCalc}</p>
                        <b class="common-span">${total}元</b>
                        <h2 class="common-h2">应缴金额</h2>
                    </div>
                </td>
            </tr>
                    <tr class="usage-row">
                <td>
                    <div class="common-div-left">
                        <h2 class="common-h2">用水量</h2>
                        <p>水${waterUsageCalc}</p>
                        <span class="common-span">${waterUsage}吨</span>
                    </div>
                </td>
                <td>
                    <div class="common-div-right">
                        <h2 class="common-h2">用电量</h2>
                        <p>电${electricityUsageCalc}</p>
                        <span class="common-span">${electricityUsage}度</span>
                    </div>
                </td>
            </tr>
            <tr class="fees-row">
                <td>
                    <div class="common-div-left">
                        <h2 class="common-h2">水费</h2>
                        <p>${waterFeeCalc}</p>
                        <span class="common-span">${waterFee}元</span>
                    </div>
                </td>
                <td>
                    <div class="common-div-right">
                        <h2 class="common-h2">电费</h2>
                        <p>${electricityFeeCalc}</p>
                        <span class="common-span">${electricityFee}元</span>
                    </div>
                </td>
            </tr>
            </tr>
            <tr class="remarks-row">
                <td colspan="2">
                    <div><b>备注:</b><span>${record.备注}</span> </div>
                </td>
            </tr>
                  </table>
                    <div class="total-cost">
                     <h3>${rentRecords[0].日期.substring(0, 5)}${rentRecords[0].日期.substring(5, 7)}到${record.日期.substring(0, 5)}${record.日期.substring(5, 7)}
                        </br>总缴费用<b>${totalRent + totalWaterFee + totalElectricityFee}元</b></h3>
                       <sub>总房租 <b>${totalRent}元</b> </sub>   <sub>总水电费 <b>${totalWaterFee + totalElectricityFee}元</b> </sub>
                       </br>
                       <sub>总用水量 <b>${totalWaterUsage}吨</b> </sub>
                       <sub>总水费 <b>${totalWaterFee}元</b> </sub>
                       </br>
                       <sub>总用电量 <b>${totalElectricityUsage}度</b> </sub>
                       <sub>总电费 <b>${totalElectricityFee}元</b> </sub>
                       </div>
                </details>
            </div>
            `;
			});
			// 设置整个内容区域
			contentArea.innerHTML = content;
			// 最后添加脚注
			const footerArea = document.querySelector('.table-footer');
			footerArea.innerHTML = `<div class="footer-cell" colspan="2">到底了,没有更多了!</div>`;
		}

		function updateLocalStorage() {
			// 仅在添加或更新时调用此函数
			localStorage.setItem('房租记录', JSON.stringify(rentRecords));
		}
		// 添加新记录的功能
		document.getElementById('addButton').addEventListener('click', function() {
			const dateInput = document.getElementById('dateInput').value;
			const rentInput = parseFloat(document.getElementById('rentInput').value) || 0;
			const waterInput = parseFloat(document.getElementById('waterInput').value) || 0;
			const electricInput = parseFloat(document.getElementById('electricInput').value) || 0;
			const noteInput = document.getElementById('noteInput').value;
			// 检查日期是否有效
			if (!dateInput) {
				alert("请填写有效的日期。");
				return;
			}
			// 创建新记录对象
			const newRecord = {
				"日期": new Date(dateInput).toLocaleDateString('zh-CN', {
					year: 'numeric',
					month: 'numeric',
					day: 'numeric'
				}),
				"房租": rentInput,
				"水表": waterInput,
				"电表": electricInput,
				"备注": noteInput,
				"禁止删除": false // 新增加的记录默认为可以删除
			};
			// 将新记录添加到数组
			rentRecords.push(newRecord);
			// 更新 localStorage
			updateLocalStorage();
			// 清空输入框
			document.getElementById('dateInput').value = '';
			document.getElementById('rentInput').value = '';
			document.getElementById('waterInput').value = '';
			document.getElementById('electricInput').value = '';
			document.getElementById('noteInput').value = '';
			// 渲染数据
			renderData();
		});
		// 更新 localStorage 的函数
		function updateLocalStorage() {
			// 仅在添加或更新时调用此函数
			localStorage.setItem('房租记录', JSON.stringify(rentRecords));
		}
		// 创建新记录对象
		const newRecord = {
			"日期": new Date(dateInput).toLocaleDateString('zh-CN', {
				year: 'numeric',
				month: 'numeric',
				day: 'numeric'
			}),
			"房租": rentInput,
			"水表": waterInput,
			"电表": electricInput,
			"备注": noteInput,
			"禁止删除": false // 新增加的记录默认为可以删除
		};
		// 添加删除功能
		document.getElementById('deleteButton').addEventListener('click', function() {
			const checkedBoxes = document.querySelectorAll('.recordCheckbox:checked');
			if (checkedBoxes.length === 0) {
				alert('请至少选择一个记录来删除。');
				return;
			}
			const confirmDelete = confirm('您确定要删除选中的记录吗?');
			if (!confirmDelete) {
				return; // 用户选择了取消,不执行删除
			}
			checkedBoxes.forEach(checkbox => {
				const index = parseInt(checkbox.dataset.index, 10);
				const record = rentRecords[index];
				// 只删除不带有 '禁止删除': true 的记录
				if (!record.禁止删除) {
					rentRecords.splice(index, 1); // 从数组中删除记录
				} else {
					alert(`本地记录 '${record.日期}' 不允许删除。`); // 提示用户该记录不可删除
				}
			});
			// 更新 localStorage 和重新渲染数据
			updateLocalStorage();
			renderData();
		});
		/* 调整所有输入框宽度*/
		function adjustAllInputWidths() {
			document.querySelectorAll('.input-length').forEach(adjustWidth); // 遍历所有类名为 'input-length' 的输入框
		}

		function adjustWidth(input) {
			const span = document.createElement('span');
			span.style.visibility = 'hidden';
			span.style.whiteSpace = 'pre';
			span.style.font = getComputedStyle(input).font;
			span.style.padding = getComputedStyle(input).padding; // 添加 padding
			span.style.border = getComputedStyle(input).border; // 添加 border
			span.style.boxSizing = 'content-box'; // 确保不计算 border 和 padding
			span.innerText = input.value || '0';
			document.body.appendChild(span);
			input.style.width = `${span.offsetWidth}px`;
			document.body.removeChild(span);
		}
		// 页面加载完成后执行
		window.onload = () => {
			renderData(); // 渲染数据
			adjustAllInputWidths(); // 然后调整输入框宽度
		};
		/* 调整所有输入框宽度 结束*/
	</script>
</html>
相关推荐
青皮桔28 分钟前
CSS实现百分比水柱图
前端·css
失落的多巴胺28 分钟前
使用deepseek制作“喝什么奶茶”随机抽签小网页
javascript·css·css3·html5
DataGear32 分钟前
如何在DataGear 5.4.1 中快速制作SQL服务端分页的数据表格看板
javascript·数据库·sql·信息可视化·数据分析·echarts·数据可视化
影子信息34 分钟前
vue 前端动态导入文件 import.meta.glob
前端·javascript·vue.js
青阳流月35 分钟前
1.vue权衡的艺术
前端·vue.js·开源
样子201839 分钟前
Vue3 之dialog弹框简单制作
前端·javascript·vue.js·前端框架·ecmascript
kevin_水滴石穿40 分钟前
Vue 中报错 TypeError: crypto$2.getRandomValues is not a function
前端·javascript·vue.js
翻滚吧键盘40 分钟前
vue文本插值
javascript·vue.js·ecmascript
孤水寒月2 小时前
给自己网站增加一个免费的AI助手,纯HTML
前端·人工智能·html
CoderLiu2 小时前
用这个MCP,只给大模型一个figma链接就能直接导出图片,还能自动压缩上传?
前端·llm·mcp