可拖动的消息框
之前看一个大神的早期博客中有一篇介绍这个的,这是地址,第一篇~第二篇。有兴趣的可以看看,然后照着里面说的做了一下:
<!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);

浙公网安备 33010602011771号