实现移动端的浮窗按钮,可拖动效果,可回弹边缘位置

首先,在HTML文件中添加一个浮窗按钮的元素,如下所示:

<div class="float-button">浮窗按钮</div>

然后,在CSS文件中设置该元素的样式,使其显示在页面的固定位置,如右下角:

.float-button {
  position: fixed;
  bottom: 20px;
  right: 20px;
  width: 100px;
  height: 40px;
  background-color: #f00;
  color: #fff;
  text-align: center;
  line-height: 40px;
  cursor: pointer;
}

接下来,使用JavaScript来实现浮窗按钮的长按移动效果。首先,监听按钮元素的touchstart事件,当长按时开始监听touchmove事件;当手指离开屏幕时,停止监听touchmove事件

var floatButton = document.querySelector('.float-button');
var isMoving = false;
var startX = 0;
var startY = 0;

floatButton.addEventListener('touchstart', function(e) {
  e.preventDefault();
  isMoving = true;
  startX = e.touches[0].clientX;
  startY = e.touches[0].clientY;
});

floatButton.addEventListener('touchmove', function(e) {
  e.preventDefault();
  
  if (!isMoving) return;
  
  var offsetX = e.touches[0].clientX - startX;
  var offsetY = e.touches[0].clientY - startY;
  
  floatButton.style.transform = 'translate(' + offsetX + 'px, ' + offsetY + 'px)';
});

floatButton.addEventListener('touchend', function(e) {
  e.preventDefault();
  isMoving = false;
});

但是,这么写得话会有一个bug,第二次移动时按钮回到了原来的初始位置,主要问题是因为在touchmove事件中,计算的偏移量是相对于起始位置的偏移量,并且每次移动都是基于上一次的位置进行计算。所以,在第二次移动时,起始位置是上一次移动结束后的位置,而不是初始位置。

为解决这个问题,可以将起始位置设为固定值,而不是每次移动结束后的位置。即,在touchstart事件中,将起始位置设置为固定值,如按钮元素的初始位置。

var floatButton = document.querySelector('.float-button');
var floatButtonRect = floatButton.getBoundingClientRect(); // 获取按钮元素的矩形信息
var isMoving = false;
var btnWidth = floatButtonRect.width;
var btnHeight = floatButtonRect.height;
// 让元素每次处于中心位置
var startX = floatButtonRect.left + btnWidth / 2;
var startY = floatButtonRect.top + btnHeight / 2;
var startX = floatButtonRect.left;
var startY = floatButtonRect.top;

floatButton.addEventListener('touchstart', function(e) {
  e.preventDefault();
  isMoving = true;
});

floatButton.addEventListener('touchmove', function(e) {
  e.preventDefault();
  
  if (!isMoving) return;
  
  var offsetX = e.touches[0].clientX - startX;
  var offsetY = e.touches[0].clientY - startY;
  
  floatButton.style.transform = 'translate(' + offsetX + 'px, ' + offsetY + 'px)';
});

floatButton.addEventListener('touchend', function(e) {
  e.preventDefault();
  isMoving = false;
});

通过这样修改后,无论进行多次移动,按钮的起始位置都是固定的初始位置,而不会发生偏移。这样,按钮就能在长按移动时始终跟随手指移动。

优化:解决点击事件失效问题;解决超过边缘范围问题

新增需求:浮窗按钮移动结束后,回到边缘位置

var floatButton = document.querySelector('.float-button');
var floatButtonRect = floatButton.getBoundingClientRect(); // 获取按钮元素的矩形信息
var isMoving = false;
var btnWidth = floatButtonRect.width; // 浮窗的宽度
var btnHeight = floatButtonRect.height; // 浮窗的高度
// 获取屏幕宽度和高度
var screenWidth = window.innerWidth;
var screenHeight = window.innerHeight;
//让浮窗按钮跟着手指居中显示
var startX = floatButtonRect.left + btnWidth / 2;
var startY = floatButtonRect.top + btnHeight / 2;

var pageX, pageY, offsetX, offsetY
floatButton.addEventListener('touchstart', (e) => {
	// e.preventDefault();
	isMoving = true;
});

floatButton.addEventListener('touchmove', (e) => {
	e.preventDefault();
	if (!isMoving) return;
	pageX = e.touches[0].clientX
	pageY = e.touches[0].clientY
	// 处理浮窗按钮左右边缘位置
	offsetX = pageX + btnWidth / 2 >= screenWidth ? screenWidth - btnWidth / 2 - startX :
						pageX < btnWidth / 2 ? btnWidth / 2 - startX : pageX - startX;
	// 处理浮窗按钮上下边缘位置
	offsetY = pageY + btnHeight / 2 >= screenHeight ? screenHeight - btnHeight / 2 -
						startY : pageY < btnHeight / 2 ? btnHeight / 2 - startY : pageY - startY;
	floatButton.style.transform = 'translate(' + offsetX + 'px, ' + offsetY + 'px)';
				});
floatButton.addEventListener('touchend', (e) => {
	// e.preventDefault();
	isMoving = false;
	// 计算按钮回到屏幕边缘的偏移量
	offsetX = pageX > screenWidth / 2 ? screenWidth - btnWidth / 2 - startX : btnWidth / 2 - startX
	// 设置按钮的最终位置
	floatButton.style.transform = 'translate(' + offsetX + 'px, ' + offsetY + 'px)';
});

注意:touchstarttouchmovetouchend事件在移动端触发,对于PC端可以使用mousedownmousemovemouseup事件替代。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
可以通过以下步骤实现 H5 可拖动悬浮按钮效果: 1. 在 HTML 文件中添加一个按钮元素,并为其设置 id 和 class: ```html <button id="drag-btn" class="drag-btn">拖动我</button> ``` 2. 在 CSS 文件中为按钮元素设置样式,使其成为一个圆形的悬浮按钮: ```css .drag-btn { position: fixed; bottom: 20px; right: 20px; width: 50px; height: 50px; border-radius: 50%; background-color: #007bff; color: #fff; font-size: 20px; font-weight: bold; text-align: center; line-height: 50px; cursor: move; } ``` 3. 在 JavaScript 文件中为按钮元素添加拖动事件: ```js var dragBtn = document.getElementById('drag-btn'); // 记录鼠标按下时的坐标和按钮的初始位置 var startX, startY, initialPos; // 鼠标按下事件 dragBtn.addEventListener('mousedown', function(e) { startX = e.clientX; startY = e.clientY; initialPos = getPosition(dragBtn); // 添加鼠标移动和松开事件 document.addEventListener('mousemove', dragBtnMouseMove); document.addEventListener('mouseup', dragBtnMouseUp); }); // 鼠标移动事件 function dragBtnMouseMove(e) { var dx = e.clientX - startX; var dy = e.clientY - startY; dragBtn.style.left = initialPos.x + dx + 'px'; dragBtn.style.top = initialPos.y + dy + 'px'; } // 鼠标松开事件 function dragBtnMouseUp(e) { document.removeEventListener('mousemove', dragBtnMouseMove); document.removeEventListener('mouseup', dragBtnMouseUp); } // 获取元素的坐标 function getPosition(element) { var rect = element.getBoundingClientRect(); return { x: rect.left, y: rect.top }; } ``` 这样就可以实现一个可拖动悬浮按钮了。通过记录鼠标按下时的坐标和按钮的初始位置,然后在鼠标移动事件中计算偏移量并改变按钮位置,最后在鼠标松开事件中移除事件监听器,就能实现拖动功能。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值