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

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>
相关推荐
学习前端的小z2 分钟前
【前端】深入理解 JavaScript 逻辑运算符的优先级与短路求值机制
开发语言·前端·javascript
前端百草阁25 分钟前
【TS简单上手,快速入门教程】————适合零基础
javascript·typescript
彭世瑜26 分钟前
ts: TypeScript跳过检查/忽略类型检查
前端·javascript·typescript
FØund40426 分钟前
antd form.setFieldsValue问题总结
前端·react.js·typescript·html
Backstroke fish27 分钟前
Token刷新机制
前端·javascript·vue.js·typescript·vue
zwjapple27 分钟前
typescript里面正则的使用
开发语言·javascript·正则表达式
小五Five28 分钟前
TypeScript项目中Axios的封装
开发语言·前端·javascript
小曲程序28 分钟前
vue3 封装request请求
java·前端·typescript·vue
临枫54129 分钟前
Nuxt3封装网络请求 useFetch & $fetch
前端·javascript·vue.js·typescript
酷酷的威朗普30 分钟前
医院绩效考核系统
javascript·css·vue.js·typescript·node.js·echarts·html5