随机定位文本悬停时显示随机排列缩略图的实现需求
实现悬停文本时淡入随机排列的缩略图(满足可扩展/随机位置要求)
需求:当用户悬停不同文本时,淡入显示一组随机排列的缩略图
需满足以下要求:
- 缩略图需保持在对应文本附近
- 缩略图可重叠但不能完全覆盖
- 文本和缩略图的位置在每次页面刷新时均为随机
- 文本和缩略图不能超出屏幕范围
- 具备可扩展性(最多支持10个文本,每个文本对应最多10个缩略图,必要时可呈同心圆分布)
原代码存在固定位置、扩展性差、无随机逻辑等问题,以下是重构后的完整实现:
实现思路
- 动态生成文本节点及对应缩略图容器,通过配置参数控制数量,满足扩展性要求
- 页面加载时随机计算每个文本的屏幕位置,确保不超出视口范围
- 悬停文本时,基于文本位置生成缩略图坐标:数量较少时随机分布,数量较多时自动切换为同心圆布局,避免完全覆盖
- 使用
fadeIn()/fadeOut()实现平滑的淡入淡出效果
完整代码
HTML
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <div class="hover-container"></div>
CSS
* { margin: 0; padding: 0; box-sizing: border-box; } body { overflow: hidden; } .hover-text { position: absolute; padding: 8px 12px; background: #fff; border: 1px solid #ddd; border-radius: 4px; cursor: pointer; user-select: none; font-size: 14px; } .thumb-group { position: absolute; pointer-events: none; } .thumb { position: absolute; width: 100px; height: 100px; border-radius: 4px; overflow: hidden; display: none; transition: all 0.3s ease; } .thumb img { width: 100%; height: 100%; object-fit: cover; }
JavaScript
$(document).ready(function() { // 可配置参数,按需调整 const CONFIG = { maxTexts: 5, maxThumbsPerText: 6, thumbSize: 100, textOffset: 150, minOverlap: 20 }; const container = $('.hover-container'); const windowWidth = $(window).width(); const windowHeight = $(window).height(); // 生成指定范围的随机整数 function getRandom(min, max) { return Math.floor(Math.random() * (max - min + 1)) + min; } // 计算文本的随机位置(确保不超出屏幕) function getTextPosition(textWidth, textHeight) { return { left: getRandom(0, windowWidth - textWidth), top: getRandom(0, windowHeight - textHeight) }; } // 计算缩略图位置:随机分布/同心圆分布 function getThumbPositions(textCenterX, textCenterY, count) { const positions = []; // 缩略图数量超过6时用同心圆布局 if (count > 6) { const radiusStep = CONFIG.textOffset / Math.ceil(count / 6); let currentRadius = radiusStep; const angleStep = 360 / 6; let angle = 0; for (let i = 0; i < count; i++) { if (i % 6 === 0 && i !== 0) currentRadius += radiusStep; const radian = (angle * Math.PI) / 180; let x = textCenterX + currentRadius * Math.cos(radian) - CONFIG.thumbSize/2; let y = textCenterY + currentRadius * Math.sin(radian) - CONFIG.thumbSize/2; // 边界校验 x = Math.max(0, Math.min(x, windowWidth - CONFIG.thumbSize)); y = Math.max(0, Math.min(y, windowHeight - CONFIG.thumbSize)); positions.push({x, y}); angle += angleStep; } } else { // 随机分布,确保最小间距 for (let i = 0; i < count; i++) { let x, y; do { x = getRandom(textCenterX - CONFIG.textOffset, textCenterX + CONFIG.textOffset) - CONFIG.thumbSize/2; y = getRandom(textCenterY - CONFIG.textOffset, textCenterY + CONFIG.textOffset) - CONFIG.thumbSize/2; x = Math.max(0, Math.min(x, windowWidth - CONFIG.thumbSize)); y = Math.max(0, Math.min(y, windowHeight - CONFIG.thumbSize)); // 检查是否与已有位置过度重叠 const hasOverlap = positions.some(pos => Math.abs(pos.x - x) < CONFIG.minOverlap && Math.abs(pos.y - y) < CONFIG.minOverlap ); if (!hasOverlap) break; } while (true); positions.push({x, y}); } } return positions; } // 动态生成文本和缩略图 for (let i = 0; i < CONFIG.maxTexts; i++) { // 创建文本节点并设置随机位置 const textEl = $(`<div class="hover-text">文本${i+1}</div>`); container.append(textEl); const textWidth = textEl.width(); const textHeight = textEl.height(); const textPos = getTextPosition(textWidth, textHeight); textEl.css({ left: `${textPos.left}px`, top: `${textPos.top}px` }); // 创建缩略图组容器 const thumbGroup = $(`<div class="thumb-group"></div>`); container.append(thumbGroup); // 生成随机数量的缩略图并设置位置 const thumbCount = getRandom(3, CONFIG.maxThumbsPerText); const thumbPositions = getThumbPositions(textPos.left + textWidth/2, textPos.top + textHeight/2, thumbCount); for (let j = 0; j < thumbCount; j++) { const thumbEl = $(` <div class="thumb"> <img src="https://placeimg.com/100/100/${['animals','people','tech','nature','arch'][getRandom(0,4)]}" alt="缩略图${j+1}"> </div> `); thumbEl.css({ left: `${thumbPositions[j].x}px`, top: `${thumbPositions[j].y}px` }); thumbGroup.append(thumbEl); } // 绑定悬停事件 textEl.hover( () => thumbGroup.find('.thumb').fadeIn(300), () => thumbGroup.find('.thumb').fadeOut(300) ); } });
关键特性说明
- 扩展性:通过
CONFIG参数可快速调整文本和缩略图的最大数量,无需修改核心逻辑 - 随机位置:页面加载时自动计算文本的随机坐标,悬停时生成缩略图的随机/同心圆位置
- 边界控制:所有元素位置计算时都会校验是否超出屏幕范围,确保显示完整
- 避免完全覆盖:随机分布时检查最小间距,数量多时自动切换为同心圆布局,保证缩略图可见
- 平滑效果:使用淡入淡出替代生硬的显示/隐藏,提升交互体验
内容的提问来源于stack exchange,提问作者kylie2675647
相关产品推荐
相关产品推荐

