JS简单实现兼容移动端/PC端悬浮模块的拖动效果
后端程序员进攻前端啦,有个可拖动悬浮按钮需求,做个笔录。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>兼容移动端/PC端悬浮模块拖动效果</title>
<style>
* {
margin: 0;
}
body{
width: 100%;
height: 2000px;
}
#box{
width: 100%;
height: 1000px;
border: 1px solid black;
}
#model{
position: absolute;
top:0;
left:0;
width: 100px;
height: 100px;
background: #bbbbbb;
}
</style>
</head>
<body>
<div id="box">
<div id="model"></div>
</div>
<script>
/**
* 简单实现悬浮模块拖动效果,此外加了悬浮模块靠左居左,靠右居右,
* 可延申添加类似ios AssistiveTouch的实现,本方法未加靠上居上和靠下居下的功能。
* @param model 可拖动元素
* @param box 拖动元素的父元素,也是拖动元素位置范围的限制元素
* @constructor
*/
var ModelMoveUtil = function (model,box) {
var flag = false;
var boxWidth = box.offsetWidth,
boxHeight = box.offsetHeight,
modelWidth = model.offsetWidth,
modelHeight = model.offsetHeight;
var cur = {
x:0,
y:0
};
var moveX,moveY,modelX,modelY,x,y;
function down(event){
flag = true;
var touch ;
if(event.touches){
touch = event.touches[0];
}else {
touch = event;
}
cur.x = touch.clientX;//点击位置的X坐标
cur.y = touch.clientY;//点击位置的Y坐标
modelX = model.offsetLeft;//模块的X坐标
modelY = model.offsetTop;//模块的Y坐标
// console.log("点击:cur={"+cur.x+","+cur.y+"}, modelX="+modelX+", modelY="+modelY);
}
function move(event){
if(flag) {
//阻止页面的滑动默认事件
event.preventDefault();
// console.log("点击:cur={" + cur.x + "," + cur.y + "}");
var touch;
if (event.touches) {
touch = event.touches[0];
} else {
touch = event;
}
moveX = touch.clientX - cur.x;//与初始位置相对,X坐标的移动距离
moveY = touch.clientY - cur.y;//与初始位置相对,Y坐标的移动距离
x = modelX + moveX;//当前模块的X坐标
y = modelY + moveY;//当前模块的Y坐标
if (x < 0) {
model.style.left = 0;
} else if (x > (boxWidth - modelWidth)) {
model.style.right = 0;
} else {
model.style.left = x + "px";
}
if ( y < 0) {
model.style.top = 0 + "px";
} else if(y > (boxHeight - modelHeight)){
model.style.bottom = 0;
} else {
model.style.top = y + "px";
}
// document.addEventListener("touchmove",function(e){
// // 判断默认行为是否可以被禁用
// if (e.cancelable) {
// // 判断默认行为是否已经被禁用
// if (!e.defaultPrevented) {
// e.preventDefault();
// }
// }
// },false);
}
}
//鼠标释放时候的函数
function end(event){
flag = false;
var nowModelX = model.offsetLeft;
var nowModelY = model.offsetTop;
var pointX = nowModelX + modelWidth/2;
var pointY = nowModelY + modelHeight/2;
// console.log("模块中心坐标:(" + pointX+","+ pointY+")");
if(pointX < boxWidth/2){
model.style.left = 0;
}else{
model.style.left = (boxWidth - modelWidth) + "px";
}
}
model.addEventListener("mousedown",function(e){
down(e);
},false);
model.addEventListener("touchstart",function(e){
down(e);
},false);
model.addEventListener("mousemove",function(e){
move(e);
},false);
model.addEventListener("touchmove",function(e){
move(e);
},false);
document.body.addEventListener("mouseup",function(e){
end(e);
},false);
model.addEventListener("touchend",function(e){
end(e);
},false);
};
var model = document.getElementById("model");
var box = document.getElementById("box");
new ModelMoveUtil(model,box);
</script>
</body>
</html>
关于
move()
方法中的阻止页面默认滑动事件,好像并未生效,而该方法中最后被注释掉的部分,网上查的结果说是:新版chrome,给这个preventDefault返回了naive,不再是清除浏览器默认行为了(可参考),便加上防止报错,后来注释掉后直接在方法内部最开始加上也不报错,未深入研究。