如何实现未知高度的底部粘性div点击滑入视口?
实现自适应高度的底部滑出盒子(初始隐藏,点击展开)
需求说明
需要实现一个绿色底部盒子,满足以下要求:
- 初始状态仅露出顶部触发区域,其余部分隐藏在视口外
- 点击触发区域后,盒子向上滑出完全展示;再次点击则收起
- 盒子高度不固定,无需手动设置
bottom的固定数值 - 窗口大小调整时,盒子始终固定在视口底部
实现方案
核心思路是通过JavaScript动态计算盒子整体高度和触发栏高度,动态设置初始bottom值,结合CSS过渡实现平滑滑动,同时监听窗口resize事件确保自适应。
具体实现步骤
CSS配置
- 给盒子添加
fixed定位确保固定在底部,设置transition: bottom 0.3s ease实现平滑动画 - 给触发栏设置样式,确保高度可被准确获取
- 给盒子添加
JavaScript逻辑
- 初始化时计算盒子总高度和触发栏高度,设置初始
bottom值为-(盒子总高度 - 触发栏高度),仅露出触发区域 - 点击触发区域时,切换
data-state状态,根据状态设置bottom值(展开时设为0,收起时恢复初始计算值) - 监听窗口
resize事件,重新计算高度并更新位置,保证窗口变化时仍保持正确状态
- 初始化时计算盒子总高度和触发栏高度,设置初始
完整代码
<!doctype html> <html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <script src="https://cdn.tailwindcss.com"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <style> #time-trigger { transition: bottom 0.3s ease; right: 1rem; width: 300px; } </style> </head> <body class="overflow-hidden h-screen m-4"> <!-- 底部滑出盒子 --> <div id="time-trigger" class="fixed bottom-0" data-state="closed"> <!-- 绿色触发区域 --> <div class="trigger-bar cursor-pointer flex rounded-t-lg bg-green-600 justify-center items-center text-white leading-10"> <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-6 h-6 mr-2"> <path stroke-linecap="round" stroke-linejoin="round" d="M12 6v6h4.5m4.5 0a9 9 0 11-18 0 9 9 0 0118 0z" /> </svg> <span>Time Trigger</span> </div> <!-- 内容区域 --> <div class="bg-white text-black p-4"> Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. </div> </div> <script> $(function() { const $trigger = $("#time-trigger"); const $triggerBar = $(".trigger-bar"); // 计算初始bottom值 function calculateInitialBottom() { const totalHeight = $trigger.outerHeight(); const barHeight = $triggerBar.outerHeight(); return `-${totalHeight - barHeight}px`; } // 初始化设置位置 function initTriggerPosition() { if ($trigger.attr('data-state') === "closed") { $trigger.css("bottom", calculateInitialBottom()); } } // 初始化执行 initTriggerPosition(); // 点击切换逻辑 $trigger.on("click", function() { if ($trigger.attr('data-state') === "closed") { $trigger.css("bottom", "0"); $trigger.attr("data-state", "open"); } else { $trigger.css("bottom", calculateInitialBottom()); $trigger.attr("data-state", "closed"); } }); // 窗口resize时重新计算 $(window).on("resize", function() { initTriggerPosition(); }); }); </script> </body> </html>
代码说明
- 将触发栏改为绿色(
bg-green-600),符合需求 - 移除原代码中手动设置的固定
bottom值,改为根据盒子高度动态计算 - 添加CSS过渡动画,让滑动效果更流畅
- 监听窗口
resize事件,确保窗口尺寸变化时,关闭状态下的盒子始终仅露出触发栏 - 保留原示例的盒子宽度和右侧边距,保持布局一致性
内容的提问来源于stack exchange,提问作者Raymond Eiber
相关产品推荐
相关产品推荐

