/*<div id="a" style="width: 200px;height: 200px;background-color:pink;position: absolute"></div>
* drag("#a"); 让你的浮动框 可以拉动,也可以跟随滚动条移动
* */
var drag = function(obj) {
//记录旧上下滑动值
var oldscrollTop = 0;
//记录旧左右滑动值
var oldscrollLeft = 0 ;
//记录一开始浮动块的位置
var top = obj.css('top').replace('px','');
var left = obj.css('left').replace('px','');
$(window).scroll(function(event){
//获取上下滚动条,已经滚动距离
let scrollTop = $(window).scrollTop();
//获取左右滚动条,已经滚动距离
let scrollLeft = $(window).scrollLeft();
//用旧滑动值和新的滑动值比较,在判断触发事件的时候是左右还是上下。
if (oldscrollTop === scrollTop ){
obj.stop().animate({ left:(left*1 + scrollLeft*1) }, 'normal',function () {
//用于比较判断
oldscrollLeft = scrollLeft;
});
return;
}
//在滑轮滚动的时候, 滑块一开始位置的值+滚动值 = 新滑块位置值;
obj.stop().animate({ top:(top*1 + scrollTop*1) }, 'normal',function () {
//用于比较判断
oldscrollTop = scrollTop;
});
})
obj.bind("mousedown", start);
function start(event) {
let e = event || window.event;
if (event.button == 0) { //判断是否点击鼠标左键
/*
* clientX和clientY代表鼠标当前的横纵坐标
* offset()该方法返回的对象包含两个整型属性:top 和 left,以像素计。此方法只对可见元素有效。
* bind()绑定事件,同样unbind解绑定,此效果的实现最后必须要解绑定,否则鼠标松开后拖拽效果依然存在
* getX获取当前鼠标横坐标和对象离屏幕左侧距离之差(也就是left)值,
* getY和getX同样道理,这两个差值就是鼠标相对于对象的定位,因为拖拽后鼠标和拖拽对象的相对位置是不变的
*/
gapX = e.clientX - obj.offset().left;
gapY = e.clientY - obj.offset().top;
//movemove事件必须绑定到$(document)上,鼠标移动是在整个屏幕上的
$(document).bind("mousemove", move);
//此处的$(document)可以改为obj
$(document).bind("mouseup", stop);
}
return false; //阻止默认事件或冒泡
}
function move(event) {
obj.css({
"left": (event.clientX - gapX) + "px",
"top": (event.clientY - gapY) + "px"
});
return false; //阻止默认事件或冒泡
}
function stop() {
//解绑定,这一步很必要,前面有解释
$(document).unbind("mousemove", move);
$(document).unbind("mouseup", stop);
/*这一步很关键, obj.css('top').replace('px','')是记录当前位置距离,到上边界的距离,而不是屏幕可见距离。
* 当初滑动的时候是(原始位置+滑动距离 = 现在位置)
* 现在当你点击移动了滑块并且解绑后, 当前位置 off = 距离上边界的距离!!但是$(window).scrollTop()是没有变的,还是那么大。
* 所以在你再次滑动的时候,才取当前的位置值,你的滑块就飞走了。所以在每一次点击移动事件的结束时候,记录一下 当前位置减去滑动值
* !!简单来说
* 滑动事件: 当前位置top1 + 滑动距离scrollTop = 是下拉或者上拉后位置。
* 假设我移动完后,然是在页面同样的位置;但!!
* 点击移动事件: 当前位置top2 = obj.css('top').replace('px','');距离上边界的距离;
* 当我再次滑动时候 当前位置top3 已经是top2 的值 ; top3 = top2 =top1 +scrollTop;
* 如果用 top3 +scrollTop 那就马上起飞
* So 每次记录 top值
* */
top = obj.css('top').replace('px','')-$(window).scrollTop();
// oldscrollTop = $(window).scrollTop();
left = obj.css('left').replace('px','')- $(window).scrollLeft();
}
}
图一
图二 下来滚动条
图三 点击移动滑块
不难看出,如果用移动后的top值来进行滑动的话,就会出错,所以在每一次点击移动结束后,都要距离一个top = $(div).offset().top - scroll ,来等待下一次滑动!!!!
点赞或收藏,评论一下,画图不易,你也看出来了吧QAQ