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

首先,在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
    评论
你可以通过以下步骤使用 JavaScript 实现拖动悬浮按钮效果: 1. 创建一个 HTML 页面,并添加一个按钮元素。你可以使用以下代码: ```html <button id="floating-button">悬浮按钮</button> ``` 2. 在 CSS 中设置按钮元素的样式,使其看起来像一个悬浮按钮。你可以使用以下代码: ```css #floating-button { position: fixed; bottom: 20px; right: 20px; width: 50px; height: 50px; background-color: #4285f4; color: #fff; border-radius: 50%; border: none; outline: none; cursor: move; } ``` 3. 在 JavaScript 中添加事件监听器,以便在用户单击按钮时启动拖动功能。你可以使用以下代码: ```javascript // 获取悬浮按钮元素 const floatingButton = document.getElementById('floating-button'); // 定义变量,用于存储鼠标按下时的坐标 let startX, startY; // 添加鼠标按下事件监听器 floatingButton.addEventListener('mousedown', function(e) { // 记录鼠标按下时的坐标 startX = e.clientX; startY = e.clientY; // 添加鼠标移动事件监听器 document.addEventListener('mousemove', moveButton); }); // 添加鼠标松开事件监听器 document.addEventListener('mouseup', function() { // 移除鼠标移动事件监听器 document.removeEventListener('mousemove', moveButton); }); // 定义函数,用于移动悬浮按钮 function moveButton(e) { // 计算鼠标移动的距离 const deltaX = e.clientX - startX; const deltaY = e.clientY - startY; // 获取悬浮按钮的当前位置 const buttonPosition = floatingButton.getBoundingClientRect(); // 移动悬浮按钮到新的位置 floatingButton.style.left = buttonPosition.left + deltaX + 'px'; floatingButton.style.top = buttonPosition.top + deltaY + 'px'; // 更新鼠标按下时的坐标 startX = e.clientX; startY = e.clientY; } ``` 以上代码通过添加鼠标事件监听器,实现了当用户按下鼠标左键时,悬浮按钮可以跟随鼠标移动。你可以根据需要修改样式和位置参数,以适应你的代码。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值