可拖动的消息框

之前看一个大神的早期博客中有一篇介绍这个的,这是地址,第一篇~第二篇。有兴趣的可以看看,然后照着里面说的做了一下:

<!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);
posted @ 2015-12-18 17:43  卡布奇诺233  阅读(258)  评论(0编辑  收藏  举报