在现代的前端应用中,浮动面板是一个非常常见的UI组件,它能够为用户提供额外的信息和操作空间,同时又不会占据页面的主要内容区域。本文将详细记录如何实现一个带有锚点功能和可拖拽顶栏的浮动面板。
设计思路
这个浮动面板将由三个主要部分组成:父元素(floating-panel
)、标头(floating-panel-header
)和内容(floating-panel-content
)。我们将通过设置父元素的偏移值来实现浮动效果,并通过监听touchmove
事件来实现拖拽功能。
1. 父元素设计
父元素floating-panel
将作为整个浮动面板的容器。常态下,我们将为它设置一个初始的偏移值,使其位于页面的底部。
2. 标头设计
标头floating-panel-header
将作为用户交互的主要区域。它将包含一个可拖拽的顶栏,用户可以通过拖动这个顶栏来改变浮动面板的高度。我们将为这个顶栏添加touchmove
事件监听器,以便在用户拖动时动态改变父元素的偏移值。
根据设计,我们的锚点可以大概设计为三个:底部、页面一半高度、页面顶部,分别对应不同的父元素偏移值
为了实现锚点功能,可以利用touchmove
和 touchend
事件,根据 touchmove
的clientY
属性判断父元素最终的偏移值;
touchmove
和touchend
都需要动态改变父元素的偏移,最终通过touchend
来固定,以满足拖动的动画效果。
3. 内容设计
内容floating-panel-content
将展示实际的信息和操作界面。它将根据父元素的偏移值动态调整自身的高度和显示内容。
实现步骤
1. HTML结构
首先,我们需要构建浮动面板的基本HTML结构。以下是一个简单的示例:
<div className="floating-panel" id="floating-panel" style={{ transform: `translateY(${window.innerHeight - 160}px)` }}><div className="floating-panel-header" id="floating-panel-header"><div className="floating-panel-header-bar"></div></div><div className="floating-panel-content" id="floating-panel-content"><div className="content" id="content"><Content..... /></div></div>
</div>
2. CSS样式
接下来,我们需要为浮动面板添加一些基本的CSS样式。以下是一个示例:
.floating-panel {background-color: rgba(30, 30, 30, 1);border-radius: 10px;height: 100%;&-header {display: flex;justify-content: center;align-items: center;cursor: grab;height: 20px;&-bar {height: 4px;width: 30px;border-radius: 10px;background-color: rgba(79, 79, 79, 1);}}&-content {padding: 10px;overflow-y: auto;max-height: 400px; /* 根据需要调整 */}}
3. JavaScript逻辑
最后,我们需要添加一些JavaScript逻辑来实现拖拽功能和锚点功能。
const initTouch = () => {const ele = document.getElementById('floating-panel-header');const panel = document.getElementById('floating-panel');const contentEle = document.getElementById('content'); // 内容元素let transformY = window.innerHeight - 160,contentHeight = window.innerHeight - 225;ele?.addEventListener('touchmove', (e) => {e.preventDefault();const { clientY } = e.touches[0];if (clientY < 180) {transformY = 0;contentHeight = window.innerHeight - 225;} else if (clientY >= 180 && clientY < window.innerHeight / 2 + 150) {transformY = window.innerHeight / 2 - 100;contentHeight = window.innerHeight - 545;} else {transformY = window.innerHeight - 160;contentHeight = window.innerHeight - 225;}panel.style.transform = `translateY(${clientY - 50}px)`;});ele?.addEventListener('touchend', () => {panel.style.transform = `translateY(${transformY}px)`;contentEle.style.height = `${contentHeight}px`;});};
注意事项
- 在实现拖拽功能时,我们禁用了父元素的过渡效果,以确保拖拽过程中的高度变化是即时的。在拖拽结束后,我们恢复了过渡效果,以便父元素能够平滑地回到其最终位置。
- 请注意,这个示例中的拖拽功能仅适用于移动端操作。如果你需要支持web设备,可以考虑使用
mousedown
、mousemove
和mouseup
事件来实现类似的逻辑。
通过以上步骤,我们成功实现了一个带有锚点功能和可拖拽顶栏的浮动面板。这个浮动面板可以根据用户的操作动态调整其高度,并且能够快速定位到指定的锚点位置。