实现8个瓶子水位控制函数:输入超100时新增瓶子并显示对应水位
8个瓶子水位动态调整实现方案
核心思路
- 每个瓶子最大容量为100,输入值超过100时,多余部分自动分配到下一个瓶子,最多支持8个瓶子
- 动态生成瓶子元素,避免硬编码冗余HTML
- 统一处理水位计算、瓶子显示/隐藏及液体高度更新逻辑
完整实现代码
HTML
<p><input type="number" min="0" max="800" value="100" name="water-level" /></p> <div class="cont"></div>
CSS
.cont { display: flex; gap: 10px; } .bottle { display: none; }
JavaScript
const MAX_BOTTLES = 8; const BOTTLE_CAPACITY = 100; const inputWaterLevel = document.querySelector('[name=water-level]'); const container = document.querySelector('.cont'); // 创建单个瓶子的DOM结构 function createBottle(index) { const bottleDiv = document.createElement('div'); bottleDiv.className = 'bottle'; bottleDiv.dataset.index = index; bottleDiv.innerHTML = ` <svg viewBox="0 0 300 300" width="150"> <clipPath id="clip-${index}"> <rect x="118" y="68" width="64" height="228" rx="20" ry="20" /> </clipPath> <image width="300" href="https://i.ibb.co/HGFQYTj/bottle.png" /> <rect clip-path="url(#clip-${index})" class="liquid" x="115" y="58" width="70" height="233" fill="#74ccf4" /> </svg> `; return bottleDiv; } // 更新所有瓶子的显示状态和水位 function updateBottles() { const totalValue = Math.max(0, Math.min(+inputWaterLevel.value, MAX_BOTTLES * BOTTLE_CAPACITY)); const neededBottles = Math.ceil(totalValue / BOTTLE_CAPACITY); // 确保容器内有足够的瓶子元素 while (container.children.length < neededBottles) { const newIndex = container.children.length + 1; container.appendChild(createBottle(newIndex)); } // 遍历所有瓶子,设置显示状态和水位 Array.from(container.children).forEach((bottle, idx) => { const bottleIndex = idx + 1; const liquid = bottle.querySelector('.liquid'); const fullHeight = 233; // 液体rect的初始高度 const emptyY = 58; // 液体rect的初始y坐标 if (bottleIndex <= neededBottles) { bottle.style.display = 'block'; // 计算当前瓶子的水位:前n-1个瓶子满,最后一个瓶子为剩余值 const bottleValue = bottleIndex < neededBottles ? BOTTLE_CAPACITY : totalValue % BOTTLE_CAPACITY || BOTTLE_CAPACITY; const liquidHeight = (bottleValue / BOTTLE_CAPACITY) * fullHeight; const liquidY = emptyY + (fullHeight - liquidHeight); liquid.setAttribute('height', liquidHeight); liquid.setAttribute('y', liquidY); } else { bottle.style.display = 'none'; } }); } // 绑定输入事件,初始化一次 inputWaterLevel.addEventListener('input', updateBottles); updateBottles();
关键说明
- 动态生成瓶子:通过
createBottle函数批量创建瓶子结构,每个瓶子的clipPath使用唯一ID避免冲突 - 水位计算逻辑:总输入值按每个瓶子100拆分,前
n-1个瓶子保持满水位,最后一个瓶子显示剩余水量;输入值≤100时仅显示第一个瓶子 - 事件统一处理:仅绑定一次
input事件,避免原代码中重复绑定导致的多次触发问题 - 边界控制:限制输入值范围0-800,确保不会生成超过8个瓶子
内容的提问来源于stack exchange,提问作者Марта
相关产品推荐
相关产品推荐

