如何让jQuery随机分配宽度的div完美填充容器宽度?
完美填满容器宽度的随机宽度item解决方案
嘿,这个问题我太懂了!你现在的核心痛点是:动态生成的item要随机选三种宽度,但直接随机加类很容易导致最后一行(甚至中间行)右侧留空隙,毕竟随机组合的宽度总和不一定刚好是100%。而且item数量还不确定,没法提前固定布局。
下面给你一套可行的方案,既能保留宽度的随机性,又能保证每一行都完美填满容器:
思路解析
首先明确三种宽度对应的容器占比:
col-sm-2:1/6(≈16.666%)col-sm-3:1/4(25%)col-sm-4:1/3(≈33.333%)
我们需要提前定义多种宽度组合,这些组合的宽度总和刚好是100%(比如6个col-sm-2、4个col-sm-3,或者混合的col-sm-4 + col-sm-3 + col-sm-3 + col-sm-2)。然后从这些有效组合里随机挑选,逐行分配给item,直到所有item都被处理完。如果最后剩下的item不够凑任何一个完整组合,就直接平均分配它们的宽度,确保填满最后一行。
完整代码实现
HTML(和你的原代码一致)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script> <div id="container"> <div class="item">a</div> <div class="item">b</div> <div class="item">c</div> <div class="item">d</div> <div class="item">e</div> <div class="item">f</div> <div class="item">g</div> <div class="item">h</div> <div class="item">i</div> <div class="item">j</div> <div class="item">k</div> </div>
CSS(优化后适配布局)
#container {} .item { background-color: #000; height: 250px; min-width: 16.666666666%; float: left; margin-bottom: 1px; color: #FFF; border: 1px solid #FFF; box-sizing: border-box; /* 加上这个,边框不会额外撑宽容器 */ } .item.col-sm-2 { width: 16.6666666%; } .item.col-sm-3 { width: 25%; } .item.col-sm-4 { width: 33.33333333%; }
注意:新增
box-sizing: border-box可以避免边框占用额外宽度,防止布局溢出容器。
jQuery 核心逻辑
$(document).ready(function() { // 定义三种宽度类对应的容器占比 const widthMap = { "col-sm-2": 1/6, "col-sm-3": 1/4, "col-sm-4": 1/3 }; // 预定义所有宽度总和为100%的行组合,可根据需求添加更多组合增加随机性 const validRowCombinations = [ ["col-sm-2", "col-sm-2", "col-sm-2", "col-sm-2", "col-sm-2", "col-sm-2"], // 6个1/6 → 100% ["col-sm-3", "col-sm-3", "col-sm-3", "col-sm-3"], // 4个1/4 → 100% ["col-sm-4", "col-sm-4", "col-sm-4"], // 3个1/3 → 100% ["col-sm-4", "col-sm-3", "col-sm-3", "col-sm-2"], // 1/3 + 1/4+1/4 +1/6 = 100% ["col-sm-4", "col-sm-2", "col-sm-4", "col-sm-2"], // 1/3+1/6+1/3+1/6 =100% ["col-sm-3", "col-sm-2", "col-sm-3", "col-sm-2", "col-sm-2"] //1/4+1/6+1/4+1/6+1/6=100% ]; // 获取所有item并转为数组 let allItems = $("#container .item").toArray(); let remainingItems = [...allItems]; while (remainingItems.length > 0) { // 筛选出当前剩余item数量足够支撑的组合 const availableCombinations = validRowCombinations.filter(comb => comb.length <= remainingItems.length); if (availableCombinations.length === 0) { // 剩下的item不够任何预定义组合,直接平均分配宽度填满一行 const itemCount = remainingItems.length; const equalWidth = 100 / itemCount; remainingItems.forEach(item => { $(item).css("width", `${equalWidth}%`); }); break; } // 随机选一个可用的组合 const selectedCombination = availableCombinations[~~(Math.random() * availableCombinations.length)]; // 给对应数量的item添加组合里的宽度类 for (let i = 0; i < selectedCombination.length; i++) { const currentItem = remainingItems.shift(); $(currentItem).addClass(selectedCombination[i]); } } });
代码说明
- 预定义有效组合:我们提前把所有能凑满100%宽度的item组合列出来,这样每一行的宽度总和必然是容器的100%,不会留空隙。
- 动态分配组合:每次从剩余的item中,随机挑选一个能适配的组合,给对应item加类,直到处理完大部分item。
- 处理剩余item:如果最后剩下的item数量不够任何预定义组合,就直接平均分配它们的宽度,确保最后一行也填满容器。
- 随机性保留:因为每次都是从有效组合里随机选,所以item的宽度布局依然有随机性,不会显得死板。
这样不管PHP生成多少个item,都能保证容器被完美填满,右侧不会留空隙~
内容的提问来源于stack exchange,提问作者Clément Yvetot
相关产品推荐
相关产品推荐

