基于JQuery实现悬浮球效果(元素跟随手指/鼠标移动,松开后自动吸附到边缘)
前言:需要改进的地方,敬请不吝赐教。
场景:
迎新系统需要实现一个迎新助手的悬浮球效果,具体效果为:按住悬浮球后,悬浮球跟随手指移动,松手后吸附到屏幕边缘。
实现思路:
1、先在网上搜索一下相关的插件和示例,避免重复造轮子。结果发现相关的插件缺少实例而且文档大多数都为英文文档,相关示例的迁移性不好。目测需求实现起来也不难,时间紧任务重,直接用JQuery实现这个悬浮球效果。
2、首先要知道哪个事件可以获得用户的操作动作(按住,松开)。
touchstart事件:当手指触摸屏幕时候触发,即使已经有一个手指放在屏幕上也会触发。
touchmove事件:当手指在屏幕上滑动的时候连续地触发。在这个事件发生期间,调用preventDefault()事件可以阻止滚动。
touchend事件:当手指从屏幕上离开的时候触发。
3、避免用户误触,不能再用户触摸到悬浮球的时候马上跟随手指移动,要加个延时判断,实现长按X秒后跟随手指移动。
4、如何获取用户触摸位置的坐标:从touch事件中获取touches数组,数组中的touch对象包含用户触摸位置的坐标
touch对象属性 | 属性描述 |
---|---|
cientX | 触摸目标在视口中的X坐标 |
clientY | 触摸目标在视口中的Y坐标 |
pageX | 触摸目标在页面中的X坐标 |
pageY | 触摸目标在页面中的Y坐标 |
screenX | 触摸目标在屏幕中的X坐标 |
screenY | 触摸目标在屏幕中的Y坐标 |
5、实时计算并设置悬浮球的位置,使其根据手指触摸的坐标进行移动
6、松开之后,判断悬浮球主要是位于屏幕左边还是右边,根据最近的区域进行吸附
实现代码:
//悬浮球ID
var robotSideId = ".robot_side"
//悬浮球宽度
var robotSideW = 50;
//悬浮球高度
var robotSideH = 50;
var robotSideTimeOut = 0;
var canDragrobotSide = false;
var mouseX = 0;
var mouseY = 0;
$(function () {
//手指在元素上(按住)
$(robotSideId).on('touchstart', function (e) {
e.preventDefault();
//长按0.2s可拖拽
robotSideTimeOut = setTimeout(function () {
canDragrobotSide = true;
}, 200);
});
//手指离开元素(离开),悬浮球自动吸附
$(robotSideId).on('touchend', function (e) {
e.preventDefault();
clearTimeout(robotSideTimeOut);
if (!canDragrobotSide) {
return false;
}
canDragrobotSide = false;
let middle = $(window).width() / 2;
if (mouseX < middle) {
//吸附在左边(y不变,x为0)
$(robotSideId).css("right", "unset");
$(robotSideId).css("left", "0px");
} else {
//吸附在右边(y不变,x为0)
$(robotSideId).css("left", "unset");
$(robotSideId).css("right", "0px");
}
});
//手指在屏幕上发生了位移,悬浮球跟随触摸位置移动
$(robotSideId).on('touchmove', function (e) {
e.preventDefault();
if (canDragrobotSide) {
let vw = $(window).width();
let vh = $(window).height();
let touch = e.touches[0];
mouseX = touch.pageX - (document.documentElement.scrollLeft || document.body.scrollLeft);
mouseY = touch.pageY - (document.documentElement.scrollTop || document.body.scrollTop);
let robotSideX = (mouseX - (robotSideW/2));
robotSideX = (robotSideX < 0 ? 0 : robotSideX);
robotSideX = (robotSideX > (vw - robotSideW) ? (vw - robotSideW) : robotSideX);
let robotSideY = (mouseY - (robotSideH/2));
robotSideY = (robotSideY < 0 ? 0 : robotSideY);
robotSideY = (robotSideY > (vh - robotSideH) ? (vh - robotSideH) : robotSideY);
$(robotSideId).css("top", `${robotSideY}px`);
$(robotSideId).css("right", "unset");
$(robotSideId).css("left", `${robotSideX}px`);
}
});
});
文章不足之处还请斧正!
本文By:NonNullPointer --2023/01/22