第一篇,先水一下,用javascript实现简单的拖拽。主要还是想通过demo的形式总结一下各种event
对象属性。
首先先看一下,这个demo最终实现的效果:
主要涉及的属性有: MouseEvent.clientX
、MouseEvent.clientY
、htmlElement.offsetLeft
、HTMLElement.offsetTop
好,先解决这些属性是什么!
MouseEvent.clientX 和clienY
代表触发事件时鼠标在视口中的的水平距离和垂直距离
HTMLElement.offsetLeft 和offsetTop
元素从border开始到父元素的内border结束
千言万语不如来一张图说的明白:
好,概念解决了。来分析一下该怎么实现这个效果。
基础代码:
*{
padding: 0;
margin: 0;
}
#box{
height: 100px;
width: 100px;
position: absolute;
top: 50px;
left: 50px;
background: red;
}
<div id="box"></div>
var box = document.getElementById("box");
- 首先有一个点击事件。(onmousedown)
- 当触发点击事件是,我们可以根据
clientX
和clientY
获得鼠标在视口的位置
- 当触发点击事件是,我们可以根据
代码如下:
//按下触发的事件
box.onmousedown = function(e) {
//点击元素视口左边的距离,适口右边的距离
var m_x = e.clientX;
var m_y = e.clientY;
}
- 接着是鼠标的移动事件(onmouseover)
鼠标移动事件结束后,同样也可以获得结束后鼠标在视口的位置。因为是在鼠标点击后立即出发移动事件。所以移动事件需要写在点击事件中
代码如下:document.onmousemove = function(e){ //移动的距离,左边到适口的距离,和上边到适口的距离 var x = e.clientX; var y = e.clientY; }
通过前两步得到的数据,可以计算出整个拖拽事件运动的距离。通过这个距离就可以设置元素最后的位置
代码如下:var resultX = x-m_x; var resultY = y-m_y; box.style.left =resultX+"px";//元素最后的水平位置 box.style.top =resultY+"px";//元素最后的垂直位置
最后是鼠标抬起事件(onmouseup)
代码如下:document.onmouseup = function(){ document.onmousemove = null; }
先写到这,来试一下写的代码,效果如下:
这里出现了问题,第一次拖拽效果,没问题。但第二次当鼠标按下再次移动时,元素回到了视口的最左上角,即视口的(0,0)点。而我希望的是当我第二次点击拖拽时,它能在第二次点击位置开始移动。那为什么会这样呢,原因是,没有保存元素移动后的位置。所以现在需要两个值来记录元素左上顶点的位置。这时就需要offsetLeft
和offsetTop
来获取。
代码如下:
var positionx = this.offsetLeft;
var positiony = this.offsetTop;
box.style.left =positionx+ resultX+"px";
box.style.top =positiony+ resultY+"px";
这样就解决了第二次移动时元素再也不会跑到视口左上角的问题了
整个代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style>
*{
padding: 0;
margin: 0;
}
#box{
height: 100px;
width: 100px;
position: absolute;
top: 50px;
left: 50px;
background: red;
}
</style>
</head>
<body>
<div id="box"></div>
<script>
var box = document.getElementById("box");
//按下触发的时间
box.onmousedown = function(e) {
//点击元素视口左边的距离,适口右边的距离
var m_x = e.clientX;
var m_y = e.clientY;
//没有设置顶点位置,我需要每一次都保留元素顶点的位置,可以用offsetleft,offsettop
var positionx = this.offsetLeft;
var positiony = this.offsetTop;
document.onmousemove = function(e){
//移动的距离,左边到适口的距离,和上边到适口的距离
var x = e.clientX;
var y = e.clientY;
var resultX = x-m_x;
var resultY = y-m_y;
box.style.left =positionx+ resultX+"px";
box.style.top =positiony+ resultY+"px";
}
}
document.onmouseup = function(){
document.onmousemove = null;
}
</script>
</body>
</html>
写在最后
本想写个简单的案例试试手,结果却发现,想和做是两回事!还需要多多练习啊