可拖动的消息框
之前看一个大神的早期博客中有一篇介绍这个的,这是地址,第一篇~第二篇。有兴趣的可以看看,然后照着里面说的做了一下:
<!DOCTYPE html> <html> <head> <title>拖动:想去哪就去哪!</title> <style type="text/css"> *{ margin: 0; padding: 0; } #win-move{ position:absolute; width:500px; cursor: pointer; } .title{ width:100%; height:50px; background:#333; color:#eee; text-align: center; line-height: 50px; } .contenter{ width:100%; height:300px; background:#eee; color:#333; text-align: center; line-height:300px; } .disable-select * { -moz-user-select: none; -ms-user-select: none; -webkit-user-select: none; user-select: none; } </style> </head> <body> <div id="win-move"> <div class="title">我是弹窗</div> <div class="contenter">动下试试 试试就试试</div> </div> <script> var canMove = function(id){ var moveObj = null; var moveX = 0; var moveY = 0; var win = document.getElementById(id); function init(){ win.addEventListener('mousedown',down); win.addEventListener('mousemove',move); win.addEventListener('mouseup',up); } function down(e){ if(e.target.className.indexOf('title')!=1){ moveObj = e.target.offsetParent; moveX = event.clientX - moveObj.offsetLeft; moveY = event.clientY - moveObj.offsetTop; document.body.className += ' disable-select'; } } function move(e){ if(moveObj){ win.style.left = (e.clientX - moveX) + "px"; win.style.top = (e.clientY - moveY) + "px"; } } function up(e){ moveObj = null; moveX = 0; moveY = 0; document.body.className = document.body.className.replace(' disable-select', ''); } init(); } canMove("win-move"); </script> </body> </html>
最后就是这样,成功简单实现了一个可拖动的提示框功能。但是我感觉还是应该自己动手写一下,先不考虑低版本兼容性,试着对这个例子中的一些地方按自己的想法进行修改:
问题1:会有卡顿,可能是公司电脑配置比较好,没感觉出来。
问题2:鼠标快速移动时超出提示框之后,提示框会停止移动,这个问题比较明显,算是一个BUG,需要想办法解决。
问题3:提示框超出页面之后,页面会出现滚动条。
思路:1:为了兼容低版本浏览器,选择使用jquery来做。
2:大致结构进行微调。
修改前:鼠标按下——鼠标移动——鼠标弹起
修改后:鼠标按下(鼠标移动)——鼠标弹起
修改完后的代码:
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>拖动:想去哪就去哪!</title> <style type="text/css"> *{ margin: 0; padding: 0; } #win-move{ position:fixed; width:500px; cursor: pointer; } .title{ width:100%; height:50px; background:#333; color:#eee; text-align: center; line-height: 50px; } .contenter{ width:100%; height:300px; background:#eee; color:#333; text-align: center; line-height:300px; } .disable-select * { -moz-user-select: none; -ms-user-select: none; -webkit-user-select: none; user-select: none; } </style> </head> <body> <div id="win-move"> <div class="title">我是弹窗</div> <div class="contenter">动下试试 试试就试试</div> </div> <script type="text/javascript" src="jquery.min.js"></script> <script> var canMove = function(id){ var win = $("#"+id); var moveX = 0; var moveY = 0; var moveTimer = null; function init(){ win.mousedown(down); win.mouseup(up); } function down(e){ win = $(e.target.offsetParent); var ele = $(e.target); if(ele.hasClass('title')){ moveX = e.pageX - win.offset().left; moveY = e.pageY - win.offset().top; win.addClass('disable-select'); $('html').on('mousemove',move); } } function move(e){ if(win){ moveTimer = setTimeout(function(){ win.css({"left" : (e.pageX - moveX) + "px" , "top" : (e.pageY - moveY) + "px"}); }, 50); }else{ return false; } } function up(e){ win.removeClass('disable-select'); $('html').off(); moveTimer = setTimeout(function(){ win = null; }, 50); } init(); } canMove("win-move"); </script> </body> </html>
总结反思:
1.mousemove事件放在mousedown事件里来做但是没有停止,所以需要解除事件。
win.off("mousemove", move);
2.在mousemove事件中加入一个定时器来做一个缓冲处理,这样移动感觉会比较平缓一点。在mouseup事件中清除该定时器就可以了。
moveTimer = setTimeout(function(){ win.css({"left" : (e.pageX - moveX) + "px" , "top" : (e.pageY - moveY) + "px"}); }, 50);
3.原以为会稍显复杂的鼠标超出问题反而很快就找到原因了,因为原先的mousemove事件绑定到了提示框,只要改为html就可以解决了。
4.滚动条问题只要把position改为fixed布局就可以了。
5.很多问题感觉可能很难解决,但是涉及的只是并不深奥,只要想到了,解决起来很快。
后记:由于发现了一些BUG,对代码又进行了调整,主要是当鼠标弹起后立即快速移动时会执行mousemove事件,可能是事件并没有解除,开始以为是选择器问题,把win改为$('html')后问题依旧,于是就干脆整个改成了$('html').off();
还是没用,究其原因可能与事件机制方面有关,正准备具体看下,通过一个小例子能够有这么多收获有点出乎我的意料之外。
又看了半天终于找到了问题的原因,是因为定时器的缘故,导致鼠标弹起后会有延迟,以至于会短暂的运行mousemove事件。
给下面也添加了一个定时器,这样就不会产生这个问题了。
moveTimer = setTimeout(function(){
win = null;
}, 50);