下面代码中展示了"拖拽"应用
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>拖拽</title>
<style>
#box1{
width:200px;
height:200px;
background-color:#bfa;
position:absolute;
}
#box2{
width:200px;
height:200px;
background-color:pink;
position:absolute;
left:300px;
top:300px;
}
</style>
<script>
// 为onload绑定函数
window.onload = function(){
var box1 = document.getElementById("box1");
box1.onmousedown = function(){
// alert("鼠标被按下了");
document.onmousemove = function(event){
// 兼容浏览器
event = event || window.event;
var left = event.clientX;
var top = event.clientY;
box1.style.left = left + "px";
box1.style.top = top + "px";
}
}
box1.onmouseup = function(){
document.onmousemove = null;
}
}
</script>
</head>
<body>
<div id="box1"></div>
<div id="box2"></div>
</body>
</html>
上面代码中,这个地方会有点问题
onmouseup不能绑定给box1,因为,当鼠标移动到box2的这个位置,由于position层级的原因,导致此时,鼠标已经脱离了box1,但是并不会触发.onmousemove事件,因为这句话此时绑定的对象是box1,意思是,我们要将鼠标直接接触box1,并松开鼠标左键时,才生效果,显然,上面虽然鼠标在box2上面(直接接触box2),但是,由于没有直接接触box1时,才松开的鼠标左键,所以,此时box1.onmousemove事件不会被触发,但是,此时由于事件的冒泡,导致,box1仍然可以移动,也即是说,obj.onmouseup,obj.onmousemove、obj.onmousedown均需要直接接触到前面的DOM的对象"obj",这样才能触发响应的事件,当然即使是不直接的接触DOM中对应的obj,通过事件的冒泡得到的也可以
但是,上面,并不能满足我们想让box1,在鼠标移动到box2上时,就直接触发.onmouseup事件,而且.onmousemove不会被执行,最终的结果就是,.box1直接停在.box2的下面,因此,我们需要如下修改代码
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>拖拽</title>
<style>
#box1{
width:200px;
height:200px;
background-color:#bfa;
position:absolute;
}
#box2{
width:200px;
height:200px;
background-color:pink;
position:absolute;
left:300px;
top:300px;
}
</style>
<script>
// 为onload绑定函数
window.onload = function(){
var box1 = document.getElementById("box1");
box1.onmousedown = function(){
// alert("鼠标被按下了");
document.onmousemove = function(event){
// 兼容浏览器
event = event || window.event;
var left = event.clientX;
var top = event.clientY;
box1.style.left = left + "px";
box1.style.top = top + "px";
}
}
document.onmouseup = function(){
console.log("触发了吗?");
document.onmousemove = null;
}
}
</script>
</head>
<body>
<div id="box1"></div>
<div id="box2"></div>
</body>
</html>
另外,需要特别注意的是,此时取消document.onmousemove的方法是,直接对该属性赋值为null,这个比较好理解,原来的document.onmousemove的属性值是一个函数对象的地址,指向的是函数,我们将该document.onmousemove的属性值修改为null之后,它将不会指向任何函数了
上面有个不完善的地方在于 ,我们将box1.onmouseup修改为document.onmouseup之后,产生了一个问题就是,我们会在文档的任何一个点击鼠标后,又松开后,就触发document.onmouseup事件,因此,我们需要在document.onmouseup里面添加如下代码
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>拖拽</title>
<style>
#box1 {
width: 200px;
height: 200px;
background-color: #bfa;
position: absolute;
}
#box2 {
width: 200px;
height: 200px;
background-color: pink;
position: absolute;
left: 300px;
top: 300px;
}
</style>
<script>
// 为onload绑定函数
window.onload = function () {
var box1 = document.getElementById("box1");
box1.onmousedown = function () {
// alert("鼠标被按下了");
document.onmousemove = function (event) {
// 兼容浏览器
event = event || window.event;
var left = event.clientX;
var top = event.clientY;
box1.style.left = left + "px";
box1.style.top = top + "px";
}
// 一定要注意,这个要写在box1.onmousedown里面,不能写在box1.onmousedown的外面
document.onmouseup = function () {
document.onmousemove = null;
alert("被触发了");
document.onmouseup = null;
}
}
}
</script>
</head>
<body>
<div id="box1"></div>
<div id="box2"></div>
</body>
</html>
另外,需要特别注意的一点时,我们写代码时,要注意应该把代码放在哪个位置,比如:上面红圈里面提到的内容,另外,特别要注意的一点是,虽然document.onmouseup要在box1.onmousedown触发之后,才有可能触发,但是由于onmouseup我绑定的对象是document,因此,只要在box1.onmousedown执行过之后,我们无论点击哪里再松开,就会触发document.onmouseup事件,因此,为了防止上面的情况发生,我们需要加入这个代码?,目的是为了让box1.onmousedown触发后,document.onmouseup只是执行一次,因为,如果,不加入下面这行代码的话,我们就没有取消document.onmouseup这个事件对应的函数
鼠标拖拽(二):解决鼠标点击后,位置不在原来在box1处的位置
修改代码如下所示:
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>拖拽(二)</title>
<style>
#box1 {
width: 200px;
height: 200px;
background-color: #bfa;
position: absolute;
}
#box2 {
width: 200px;
height: 200px;
background-color: pink;
position: absolute;
left: 300px;
top: 300px;
}
</style>
<script>
// 为onload绑定函数
window.onload = function () {
var box1 = document.getElementById("box1");
box1.onmousedown = function (event) {
// 兼容浏览器
event = event || window.event;
// 获取相对的位移
/* 注意: 下面的offsetLeft和offsetRight是给此处的box1设置的,而不是给event设置的,*/
var ol = event.clientX - box1.offsetLeft;
var ot = event.clientY - box1.offsetTop;
document.onmousemove = function (event) {
// 兼容浏览器
event = event || window.event;
var left = event.clientX;
var top = event.clientY;
box1.style.left = left -ol + "px";
box1.style.top = top - ot + "px";
/* box1.style.left = left - ol + "px";
box1.style.top = top - ot + "px"; */
// console.log("触发了吗???");
}
// 一定要注意,这个要写在box1.onmousedown里面,不能写在box1.onmousedown的外面
document.onmouseup = function () {
document.onmousemove = null;
// alert("被触发了");
document.onmouseup = null;
// alert("被触发了");
}
}
}
</script>
</head>
<body>
<div id="box1"></div>
<div id="box2"></div>
</body>
</html>
但是,要思考的是,什么时候需要用到事件对象event
响应函数里面需要加上event这个时,也就是需要用到事件对象时,这意味着为某个DOM对象绑定事件句柄时,我们需要浏览器给我们提供该事件句柄对应的事件对象的某些属性时,因为,我们不知到这个是多少,浏览器是知道的,我们需要通过浏览器告诉我们,比如上面的event.clientX返回的是mouse(鼠标的水平偏移位置)
但是,上面的代码仍然有一部分问题
当我们用力按住box1时,并拖动时,会触发浏览器的默认"拖拽事件",也就是如下所述
出现上面这种情况是,并不会触发document.onmouseup对应的响应函数,造成不好的体验,为了,解决这个问题,可以在box1.onmousedown对应的响应函数里面加上"return false"来取消这种默认的行为
下面的这种情况,也是会出现这样的情况,具体可以参见视频的出现的情况
但是,值得注意的是,return false(针对上述的这种情况)这种取消默认的行为,在IE8里面不起作用
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>拖拽(二)</title>
<style>
#box1 {
width: 200px;
height: 200px;
background-color: #bfa;
position: absolute;
}
#box2 {
width: 200px;
height: 200px;
background-color: pink;
position: absolute;
left: 300px;
top: 300px;
}
</style>
<script>
// 为onload绑定函数
window.onload = function () {
var box1 = document.getElementById("box1");
box1.onmousedown = function (event) {
// 兼容浏览器
event = event || window.event;
// 获取相对的位移
/* 注意: 下面的offsetLeft和offsetRight是给此处的box1设置的,而不是给event设置的,*/
var ol = event.clientX - box1.offsetLeft;
var ot = event.clientY - box1.offsetTop;
document.onmousemove = function (event) {
// 兼容浏览器
event = event || window.event;
/* if(box1.setCapture){
box1.setCapture();
} */
// 下面这种方法
box1.setCapture && box1.setCapture();
var left = event.clientX;
var top = event.clientY;
box1.style.left = left -ol + "px";
box1.style.top = top - ot + "px";
/* box1.style.left = left - ol + "px";
box1.style.top = top - ot + "px"; */
// console.log("触发了吗???");
}
// 一定要注意,这个要写在box1.onmousedown里面,不能写在box1.onmousedown的外面
document.onmouseup = function () {
document.onmousemove = null;
// alert("被触发了");
document.onmouseup = null;
// alert("被触发了");
/* if(box1.releaseCapture){
box1.releaseCapture();
} */
box1.releaseCapture && box1.releaseCapture();
}
return false;
}
}
</script>
</head>
<body>
加油
<div id="box1"></div>
<div id="box2"></div>
</body>
</html>