使用CSS和jQuery构建金字塔组件的动态宽度计算问题
Hey there! Let's tackle this dynamic pyramid width problem. The core issue with your current code is that you're tied to pre-written CSS classes for fixed widths, which can't scale when users can add/remove blocks freely. Here's a clean, scalable approach that calculates widths on the fly every time a block is added or removed:
Step 1: Fix the Initial Pyramid Structure
First, let's make sure the initial pyramid has its top "tip" already in place. Update your HTML to include the tip block by default:
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <ul class="pyramid"> <li> <div class="item item0"></div> </li> </ul> <section class="buttons"> <div id="add-block"> <span>Add Block</span> <div class="button">+ </div> </div> <div id="remove-block"> <span>Remove Block</span> <div class="button">- </div> </div> </section>
Step 2: Simplify CSS (Remove Fixed Width Classes)
We don't need pre-defined .item1, .item2 classes anymore. Remove those and keep only the base styles for the tip and trapezoid blocks:
.item { margin: 0 auto; position: relative; display: flex; justify-content: center; } .item0 { height: 0px; width: 0px; border-left: 50px solid transparent; border-right: 50px solid transparent; border-bottom: 60px solid #0488e0; } li div.item:not(.item0) { border-bottom: 60px solid #0488e0; border-left: 45px solid transparent; border-right: 45px solid transparent; margin-top: 10px; height: 0; }
Step 3: Add Dynamic Width Calculation in JavaScript
We'll create a reusable function to update all block widths every time a block is added or removed. This function will:
- Keep the top tip at 0 width
- Calculate each trapezoid block's width as
200px + 100px * (block index - 1)(so each new block is 100px wider than the one above it)
Here's the updated JS:
$(document).ready(function() { // Reusable function to update pyramid widths function updatePyramid() { $('.pyramid li .item').each(function(index) { if (index === 0) { // Keep the top tip styled correctly $(this).addClass('item0').css('width', '0px'); return; } // Calculate width: first trapezoid is 200px, each next is +100px const blockWidth = 200 + 100 * (index - 1); $(this).removeClass('item0').css('width', `${blockWidth}px`); }); } // Add Block Functionality $('#add-block .button').click(function() { var $block = $('<li><div class="item"><input class="input" type="text" placeholder="#" maxlength="2"></div></li>'); $('.pyramid').append($block); updatePyramid(); // Refresh widths after adding }); // Remove Block Functionality (don't remove the top tip) $('#remove-block .button').click(function() { if ($('.pyramid li').length > 1) { $('.pyramid li').last().remove(); updatePyramid(); // Refresh widths after removing } }); });
How This Works
- Initial Setup: The first
licontains the pyramid's tip (.item0) which stays fixed at the top. - Adding Blocks: Every time you click "Add Block", a new trapezoid is appended to the bottom, and
updatePyramid()recalculates all widths to ensure each new block is 100px wider than the one above it. - Removing Blocks: We prevent removing the top tip, and after removing the bottom block,
updatePyramid()ensures the remaining blocks keep their correct widths relative to the tip.
This approach is fully scalable—users can add as many blocks as they want, and the widths will always adjust correctly without any pre-written CSS classes.
内容的提问来源于stack exchange,提问作者Rummel17

