今天做一个拖拽案例,就是滚动条的一部分。当鼠标移动到滑块上并且按下时,给document绑定mousemove事件,当鼠标放开时解除mousemove事件,代码如下:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="vue/vue.2.5.js"></script> <script src="vue/jQuery.js"></script> <style> .scale{ position: absolute; left: 100px; top: 100px; width: 100px; text-align: center; } .slider_box{ position: relative; width: 1px; height: 200px; background-color: #000; margin: 10px auto; } .slider{ position: absolute; width: 18px; height: 8px; background-color: #000; border-radius: 3px; left: -8px; cursor: pointer; } </style> </head> <body> <div id="app"> </div> <div class="scale"> <!--只要界面存在其它元素,就会有bug,这是什么原因--> <a href="javascript:;" class="add">+</a> <div class="slider_box"> <div class="slider" id="box"></div> </div> <a href="javascript:;" class="reduce">-</a> </div> <script> function dragEle(opt){ //可以来点判断,当调用这个函数时输入参数错误时提示 if(!opt.dragEle){ console.log('要拖拽的元素是哪个'); } var dragEle = opt.dragEle; var dragWrap = opt.dragWrap; //原理,点击元素,获取源位置,移动鼠标,获取目标位置,鼠标移动多少元素移动多少 var sourcePos = {left:0,top:0}; var targetPos = {left:0,top:0}; var elePos = {left:0,top:0}; //元素宽高为了碰撞检测 var box = {height:dragWrap.height(),width:dragWrap.width()}; var son = {height:0,width:0}; dragEle.mousedown(function(event){ console.log('begin'); elePos.left = dragEle.position().left; elePos.top = dragEle.position().top; sourcePos.left=event.pageX; sourcePos.top=event.pageY; son.width = dragEle.width(); son.height = dragEle.height(); // console.log(event.target.classList); $(document).mousemove(function(event){ targetPos.left = event.pageX; targetPos.top = event.pageY; //这个elePos为元素位置,点击时获取 var top = elePos.top + targetPos.top - sourcePos.top; //碰撞检测 if(top<0){ top = 0; } if(top>box.height-son.height){ top = box.height-son.height; } dragEle.css({ top: top + 'px' }) }); }); $(document).mouseup(function(){ console.log('off'); $(document).off('mousemove'); }); } dragEle({ dragEle: $('.slider'), dragWrap: $('.slider_box') }); </script> </body> </html>
这时就出现了一个bug,当第一次点击滑块,鼠标移到别的地方时,正常,然后再一次点击滑块时就出现了问题。把js代码简化成下面这样,继续找问题
$('.slider').off('mousedown').on('mousedown',function(ev){ console.log('down'); $(document).off('mousemove').on('mousemove',function(ev){ console.log('move') }); }); $(document).off('mouseup').on('mouseup',function(){ console.log('up'); $(document).off('mousemove') });
当第一次点击元素,鼠标横向离开元素(上下离得远也行)放开鼠标能打印up,再一次点击,离开,放开鼠标,不能打印up。百度了好久也找不到,最后问了人才知道,当鼠标按下,并拖动时,还会触发选择功能,就是平时用鼠标选择文本复制。这时放开鼠标,它还是触发了选中其它内容的效果,所以触发不了mouseup;要给body加个 onselectstart="return false" ,然后就没有这个问题了,使用时也就是当按下鼠标时给body加上这个,放开鼠标时给body去掉这个。
但是我还有一个问题,为什么第一次正常,第二回不正常????有哪位大神能告知!!
好了,现在滚动条的一部分已经出来了,接着给它传入回调函数,就可以实现其它功能了,代码形如:
function dragEle(opt){ //可以来点判断,当调用这个函数时输入参数错误时提示 var dragEle = opt.dragEle; var callback = opt.callback; dragEle.mousedown(function(){ $(document).mousemove(function(){ callback(123) }); }); $(document).mouseup(function(){ }); } function myScroll(forParm) { console.log(forParm); } dragEle({ dragEle: $('.slider'), callback:myScroll });