大家好,我是梅巴哥er。
好久不写这种效果了,突然写起来,还真费了点力气。 放这里,以后用的时候复习一下。
下面的代码直接CV到编辑器里,用浏览器打开页面就能直接用。
原生js写的,在框架范围内,不用考虑兼容性问题。
不管用的哪种框架,拿去就能用。
web端拖动代码案例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
* {
padding: 0;
left: 0;
}
.box {
position: relative;
width: 200px;
height: 80px;
background-color: aqua;
overflow: hidden;
}
.box1 {
position: absolute;
top: 0;
left: 0;
width: 250px;
height: 100%;
background-color: pink;
}
.bar {
position: relative;
width: 200px;
height: 10px;
overflow: hidden;
}
.bar1 {
position: absolute;
top: 0;
left: 0;
width: 50%;
height: 100%;
background-color: red;
}
</style>
</head>
<body>
<div class="box">
<div class="box1">12112214311241fafgatggagtq</div>
</div>
<div class="bar">
<div class="bar1"></div>
</div>
<script>
window.addEventListener('load', function() {
var log = console.log || window.console.log;
var $ = document.querySelector.bind(document);
var box = $('.box');
var box1 = $('.box1');
var bar = $('.bar');
var bar1 = $('.bar1');
var ex; //鼠标点击box1的初始位置
var bl; //box1的初始left值
var bo; //bar1的初始left值
box1.onmousedown = function(e) {
e.preventDefault();
bl = box1.offsetLeft;
bo = bar1.offsetLeft;
ex = e.offsetX;
box1.style.cursor = 'move';
box1.onmousemove = function(e) {
if(bl + e.offsetX - ex >= 0) {
box1.style.left = 0;
bar1.style.left = 0;
} else if(bl + e.offsetX - ex <= box.offsetWidth - box1.offsetWidth) {
box1.style.left = box.offsetWidth - box1.offsetWidth + 'px';
bar1.style.left = bar.offsetWidth - bar1.offsetWidth + 'px';
} else {
box1.style.left = bl + e.offsetX - ex + 'px';
bar1.style.left = bo + (bar.offsetWidth - bar1.offsetWidth)*(e.offsetX - ex)/(box.offsetWidth - box1.offsetWidth) + 'px';
}
}
document.onmouseup = function() {
box1.onmousemove = null;
}
}
})
</script>
</body>
</html>
拖动方法在web页面的封装
function moveBarFn(obj) {
var box = $('.' + obj.box);
var box1 = $('.' + obj.box1);
var bar = $('.' + obj.bar);
var bar1 = $('.' + obj.bar1);
var ex; //鼠标点击到box1时的x位置
var bl; //box1的初始left值
var bo; //bar1的初始left值
box1.onmousedown = function(e) {
e.preventDefault();
bl = box1.offsetLeft;
bo = bar1.offsetLeft;
ex = e.offsetX;
box1.style.cursor = 'move';
box1.onmousemove = function(e) {
if(bl + e.offsetX - ex >= 0) {
box1.style.left = 0;
bar1.style.left = 0;
} else if(bl + e.offsetX - ex <= box.offsetWidth - box1.offsetWidth) {
box1.style.left = box.offsetWidth - box1.offsetWidth + 'px';
bar1.style.left = bar.offsetWidth - bar1.offsetWidth + 'px';
} else {
box1.style.left = bl + e.offsetX - ex + 'px';
bar1.style.left = bo + (bar.offsetWidth - bar1.offsetWidth)*(e.offsetX - ex)/(box.offsetWidth - box1.offsetWidth) + 'px';
}
}
document.onmouseup = function() {
box1.onmousemove = null;
}
}
}
封装后的用法
var obj = {
box: 'box',
box1: 'box1',
bar: 'bar',
bar1: 'bar1',
}
moveBarFn(obj);
注意事项(避雷针)
- 如果box1中有子盒子是带有relative定位的,
e.offsetX的值会变得混乱不堪。这是因为它的值是鼠标的点击位置和最近定位的盒子之间的距离。
以上图为例。分别点击abcde五个点,对应的e.offsetX并不是依次增加的,因为他们的相对位置是不一样的。(可以自己log输出一下看看)
-
解决办法
- 尽量避免要移动的盒子里,还存在带有定位的子盒子的情况。
- 如果不能避免,可以在box盒子里,加上一个absolute定位的遮盖层,覆盖在box1之上。
- 这样就可以让鼠标点击的是遮盖层,而非box1盒子。
- 或者干脆不用
e.offsetX, 而改用和定位无关的e.clientX。
app端的拖动代码案例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
* {
padding: 0;
left: 0;
}
.box {
position: relative;
width: 200px;
height: 80px;
background-color: aqua;
overflow: hidden;
}
.box1 {
position: absolute;
top: 0;
left: 0;
width: 250px;
height: 100%;
background-color: pink;
}
.box2 {
position: relative;
width: 100px;
height: 50px;
margin-left: 50px;
margin-top: 20px;
background-color: blue;
}
.bar {
position: relative;
width: 200px;
height: 10px;
overflow: hidden;
}
.bar1 {
position: absolute;
top: 0;
left: 0;
width: 50%;
height: 100%;
background-color: red;
}
</style>
</head>
<body>
<div class="box">
<div class="box1">12112214311241fafgatggagtq
<div class="box2"></div>
</div>
</div>
<div class="bar">
<div class="bar1"></div>
</div>
<script>
window.addEventListener('load', function() {
var log = console.log || window.console.log;
var $ = document.querySelector.bind(document);
var box = $('.box');
var box1 = $('.box1');
var bar = $('.bar');
var bar1 = $('.bar1');
box1.ontouchstart = function(e) {
e.preventDefault();
var touch = e.touches[0];
var ex = touch.clientX;
var bl = box1.offsetLeft;
var bo = bar1.offsetLeft;
box1.ontouchmove = function(e) {
var touch = e.touches[0];
if(bl + touch.clientX - ex >= 0) {
box1.style.left = 0;
bar1.style.left = 0;
} else if(bl + touch.clientX - ex <= box.offsetWidth - box1.offsetWidth) {
box1.style.left = box.offsetWidth - box1.offsetWidth + 'px';
bar1.style.left = bar.offsetWidth - bar1.offsetWidth + 'px';
} else {
box1.style.left = bl + touch.clientX - ex + 'px';
bar1.style.left = bo + (bar.offsetWidth - bar1.offsetWidth)*(touch.clientX - ex)/(box.offsetWidth - box1.offsetWidth) + 'px';
}
}
document.ontouchend = function(e) {
box1.ontouchmove = null;
}
}
})
</script>
</body>
</html>
app端拖动方法简单封装
function moveBarFn(obj) {
var box = $('.' + obj.box);
var box1 = $('.' + obj.box1);
var bar = $('.' + obj.bar);
var bar1 = $('.' + obj.bar1);
box1.ontouchstart = function(e) {
e.preventDefault();
var touch = e.touches[0];
var ex = touch.clientX;
var bl = box1.offsetLeft;
var bo = bar1.offsetLeft;
box1.ontouchmove = function(e) {
var touch = e.touches[0];
if(bl + touch.clientX - ex >= 0) {
box1.style.left = 0;
bar1.style.left = 0;
} else if(bl + touch.clientX - ex <= box.offsetWidth - box1.offsetWidth) {
box1.style.left = box.offsetWidth - box1.offsetWidth + 'px';
bar1.style.left = bar.offsetWidth - bar1.offsetWidth + 'px';
} else {
box1.style.left = bl + touch.clientX - ex + 'px';
bar1.style.left = bo + (bar.offsetWidth - bar1.offsetWidth)*(touch.clientX - ex)/(box.offsetWidth - box1.offsetWidth) + 'px';
}
}
document.ontouchend = function(e) {
box1.ontouchmove = null;
}
}
}
使用示例
var obj = {
box: 'box', //外层盒子的类名
box1: 'box1', //要移动的盒子的类名
bar: 'bar', //包裹滑动条的盒子类名
bar1: 'bar1', //滑动条的类名
}
moveBarFn(obj); //调用函数
app端注意事项
- app的
ontouchstart相当于web的onmousedown,鼠标放下,触摸屏幕 - app的
ontouchmove相当于web的onmousenove,鼠标移动 - app的
ontouchend相当于web的onmouseup,鼠标抬起,离开`屏幕 - 需要注意的是,在
ontouchstart和ontouchmove事件中,都有var touch = e.touches[0];,这是选取触摸点的,事件里都要带上,不然触摸无效。
或许还需要注意
- 看下自己的项目里,在执行完拖动时,是否还需要复位。
- 初始化,初始化,初始化对于每个项目,都相当重要。所以,适当注意是否需要复位。