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

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>
相关推荐
恋猫de小郭4 小时前
Flutter 状态管理基准测评,一个很有趣的观点
android·前端·flutter
雪芽蓝域zzs5 小时前
前端编辑组件wangEditor
前端
风骏时光牛马5 小时前
稳定性治理及疑难问题深度剖析与实战复盘
前端
JeffongTan13 小时前
在LWC中镶嵌VF Page获取用户IP
前端·javascript·salesforce
不cong明的亚子15 小时前
web live多屏互动平台
javascript·经验分享·音视频
陆枫Larry16 小时前
Astro 是什么
前端
是立不是利17 小时前
写给设计师的 CSS 博客美学指南
前端·css
dsyyyyy110118 小时前
JS复习,难点,易错点总结
开发语言·javascript·ecmascript
默_笙18 小时前
🏝 Docker 就是"房地产开发":从施工图纸到小区物业的容器化指南
前端·javascript
计算机魔术师18 小时前
Rohan Paul 谈用时间跨度衡量智能体能力,并引用 OpenAI 自动化研究实习生里程碑
前端