一只机器猫跟着鼠标跑

页面结构

很简单,就一个img

<img id='jqm' src="images/1.gif" alt="" />   

样式


#jqm{
            position: fixed;
            left: 50%;
            top: 50%;
}

js代码

这个比较容易实现,使用documentonmousemove事件,利用clientX、Y来控制机器猫的top、left就行了。

这里要注意,机器猫应该是fixed定位。

window.onload = function() { 
function $(id) {
return document.getElementById(id);
}
var jqm = $('jqm');
document.onmousemove = function() {
var event = event || window.event; //兼容ie678
var x = event.clientX;
var y = event.clientY;
jqm.style.left = x + 'px';
jqm.style.top = y + 'px';
}
}

your text

加入缓动动画

只是这样的效果不是特别好,像实现机器猫追着跑的效果,那就需要加入缓动动画,使用setInterval来动态控制

window.onload = function(argument) { 
function $(id) {
return document.getElementById(id);
}
var targetX = 0,
targetY = 0,
currentX = 0,
currentY = 0,
jqm = $('jqm');
document.onmousemove = function() {
var event = event || window.event;
var x = event.clientX;
var y = event.clientY;
targetX = x;
targetY = y;
}
setInterval(function() {
currentX += (targetX - currentX) / 10;
currentY += (targetY - currentY) / 10;
jqm.style.left = currentX + 'px';
jqm.style.top = currentY + 'px';
}, 20)
}

your text

拖着机器猫跑

这就是拖拽的简单应用,拖拽在网页中的应用很多,比如拖拽对话框,自制滚动条……

基本框架

拖拽的实现基本框架是X.onmousedown 里面套document.onmousemove

    jqm.onmousedown = function(){ 
document.onmousemove = function(){
var event = event || window.event;
var x = event.clientX;
var y = event.clientY;
jqm.style.left = x+'px';
jqm.style.top = y+'px';
}
}

鼠标弹起停止

这样基本可以实现拖着机器猫跑了,但是有个问题,当鼠标弹起后,机器猫依然在跟着鼠标跑,这时候,需要加上一个鼠标弹起事件的响应。清除onmousemove

document.onmouseup = function () { 
// body...
document.onmousemove = null;
}

但是这样还不够完善,因为偶尔我们拖机器猫的时候,会发现把机器猫的图片拖起来了,感觉就是灵魂出壳!

your text

防止选择拖动

解决这个问题也很简单,去除选中文字的功能

window.getSelection ? window.getSelection().removeAllRanges() : document.selection.empty();

完整代码

window.onload = function  (argument) { 
    function $(id){return document.getElementById(id);}
    var jqm = $('jqm');
    jqm.onmousedown = function(){
        document.onmousemove = function(){
            var event = event || window.event;
            var x = event.clientX;
            var y = event.clientY;
            jqm.style.left = x+'px';
            jqm.style.top = y+'px';  
            window.getSelection ? window.getSelection().removeAllRanges() : document.selection.empty();
        }
    }
    document.onmouseup = function () { 
        document.onmousemove = null;
    }
}

拖拽进一步

之前的拖拽因为是拖拽一个小图片所以可能没太多可以注意的地方,但是很多时候,我们拖拽的是一个比较大的对话框。而且往往是拖拽对话框的顶栏移动对话框,这时候坐标计算上可能会有点问题。

现在我们给机器猫加一个笼子,然后增加一个拖拽区。我们想实现的的是点击拖拽区拖动才能实现整个笼子拖动

<div class="box" id="box"> 
<div class="title" id="drag_area">
拖拽区
</div>
<img id='jqm' src="images/1.gif" alt="" />
</div>

样式上,我们把移动到拖拽区域的鼠标变成十字形式,也就是修改cursor:move

*{margin:0;padding:0;}
        html,body{
            height: 100%;
            overflow: hidden;
        }
        .box{
            position: fixed;
            left: 50%;
            top: 50%;
            margin-left: -100px;
            margin-top: -100px;
            width: 200px;
            height: 200px;
            border: 1px solid #333;
            position: relative;
        }
        .title{
            top: 0;
            height: 30px;
            line-height: 30px;
            text-align: center;
            background: #eee;
            cursor: move;
        }

js代码

我们把之前写的代码稍微封装一下。现在拖拽的区域对象和移动的对象不一致了。

    function DragThis(drag_obj, move_obj)
    {
        drag_obj.onmousedown = function(){
            document.onmousemove = function(){
                var event = event || window.event;
                var x = event.clientX;
                var y = event.clientY;
                targetX = x;
                targetY = y;
                move_obj.style.left = x+'px';
                move_obj.style.top = y+'px';  
                window.getSelection ? window.getSelection().removeAllRanges() : document.selection.empty();
            }
        }
    }

运行一下,貌似是实现功能了,但是和我们想象中的不太一样,因为我们点击的时候,盒子立马移动了一下,鼠标变到对话框中心去了。

your text

这是因为两点:

  1. 鼠标的坐标不等于盒子的left+top,盒子的left+top是基于左上角的
  2. 对话框因为要居中的问题,所有有个一margin-top|left:-100px,所以鼠标到对话框中心去了

解决方案:坐标补偿

解决方案也很简单,我们进行一些坐标的补偿就好了。

针对问题1,我们可以点击的时候计算出鼠标在对话框内部的偏移 ,用鼠标坐标减对话框的offsetLeft/Top就行了

        var x = event.clientX - move_obj.offsetLeft; 
var y = event.clientY - move_obj.offsetTop;

然后,在计算盒子移动的left和top的时候,减掉这个x,y就好了。

        move_obj.style.left = event.clientX - x+'px'; 
move_obj.style.top = event.clientY - y+'px';

针对问题2,由于margin-left和top进行-100px的偏移,那我们对left和top进行+100px,就行了。

    move_obj.style.left = (event.clientX - x + 100)+'px';
    move_obj.style.top = (event.clientY - y + 100)+'px';

当然,也可以把100px的计算放在x,y计算里面,只是+就变成-了。

这样,问题就解决了。

your text

最终代码

window.onload = function  (argument) {
    function $(id){return document.getElementById(id);}
    var drag=$('drag_area'),
        move=$('box');
    DragThis(drag,move);
    function DragThis(drag_obj, move_obj)
    {
        drag_obj.onmousedown = function(event){
            var x = event.clientX - move_obj.offsetLeft - 100;
            var y = event.clientY - move_obj.offsetTop - 100;
            document.onmousemove = function(){
                var event = event || window.event;
                move_obj.style.left = event.clientX - x +'px';
                move_obj.style.top = event.clientY - y +'px';  
                window.getSelection ? window.getSelection().removeAllRanges() : document.selection.empty();
            }
        }
    }
    document.onmouseup = function () { 
        document.onmousemove = null;
    }
}