鼠标行为 → 坐标系
clientX/Y
: 鼠标位置相对于当前可视区域的坐标,不包括滚动条的距离
layerX/Y
:同 pageX/Y
相同,IE11 以下和 clientX/Y
相同
screenX/Y
:鼠标位置相对于屏幕的坐标
x/y
:和 client
相同,火狐不支持,鼠标位置相对于当前可视区域的坐标,不包括滚动条的距离
pageX/pageY
:鼠标位置相对于当前文档的坐标,包括滚动条的距离,IE9以下不支持
offsetX/Y
:鼠标位置相对于块元素的坐标,包含边框,Safari 不包括边框
⭐️ 封装 - 获取鼠标相对文档位置
function pagePos(e) {
var sLeft = getScrollOffset().left,
sTop = getScrollOffset().top,
// 获取文档左边框和上边框的宽度
cLeft = document.documentElement.clientLeft || 0,
cTop = document.documentElement.clientTop || 0;
return {
X: e.clientX + sLeft - cLeft,
Y: e.clientY + sTop - cTop
}
}
拖拽 div
<!DOCTYPE html>
<html lang="en">
<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>Document</title>
<style>
body {
margin: 0;
padding: 0;
}
.box {
position: absolute;
left: 0;
top: 0;
background-color: orange;
width: 100px;
height: 100px;
}
</style>
</head>
<body>
<div class="box"></div>
<script>
function getScrollOffset() {
if (window.pageXOffset) {
return {
left: window.pageXOffset,
top: window.pageYOffset
}
} else {
return {
left: document.body.scrollLeft + document.documentElement.scrollLeft,
top: document.body.scrollTop + document.documentElement.scrollTop
}
}
}
function pagePos(e) {
var sLeft = getScrollOffset().left,
sTop = getScrollOffset().top,
cLeft = document.documentElement.clientLeft || 0,
cTop = document.documentElement.clientTop || 0;
return {
X: e.clientX + sLeft - cLeft,
Y: e.clientY + sTop - cTop
}
}
function getStyles(elem, prop) {
if (window.getComputedStyle) {
if (prop) {
return window.getComputedStyle(elem, null)[prop];
} else {
return window.getComputedStyle(elem, null);
}
} else {
if (prop) {
return window.currentStyle(elem, null)[prop];
} else {
return window.currentStyle(elem, null);
}
}
}
var box = document.getElementsByClassName("box")[0];
box.onmousedown = function(e) {
var e = e || window.event;
// 鼠标离文档左侧距离 - box离文档左侧距离 = 鼠标距box左边缘距离
var x = pagePos(e).X - parseInt(getStyles(box, 'left')),
y = pagePos(e).Y - parseInt(getStyles(box, 'top'));
document.onmousemove = function(e) {
var e = e || window.event;
// 每次再把x,y这段距离减去
box.style.left = pagePos(e).X - x + 'px';
box.style.top = pagePos(e).Y - y + 'px';
}
document.onmouseup = function(e) {
this.onmousemove = null;
this.onmouseup = null;
}
}
</script>
</body>
</html>
⭐️ 封装
<!DOCTYPE html>
<html lang="en">
<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>Document</title>
<style>
body {
margin: 0;
padding: 0;
}
.box {
position: absolute;
left: 0;
top: 0;
background-color: orange;
width: 100px;
height: 100px;
}
</style>
</head>
<body>
<div class="box"></div>
<script>
// 添加事件
function addEvent(elem, type, fn) {
if (elem.addEventListener) {
elem.addEventListener(type, fn, false);
} else if (elem.attachEvent) {
elem.attachEvent('on' + type, function() {
fn.call(elem);
})
} else {
elem['on' + type] = fn;
}
}
// 移除事件
function removeEvent(elem, type, fn) {
if (elem.addEventListener) {
elem.removeEventListener(type, fn, false);
} else if (elem.attachEvent) {
elem.detachEvent('on' + type, fn);
} else {
elem['on' + type] = null;
}
}
// 获取页面偏移
function getScrollOffset() {
if (window.pageXOffset) {
return {
left: window.pageXOffset,
top: window.pageYOffset
}
} else {
return {
left: document.body.scrollLeft + document.documentElement.scrollLeft,
top: document.body.scrollTop + document.documentElement.scrollTop
}
}
}
// 获取鼠标相对文档偏移
function pagePos(e) {
var sLeft = getScrollOffset().left,
sTop = getScrollOffset().top,
cLeft = document.documentElement.clientLeft || 0,
cTop = document.documentElement.clientTop || 0;
return {
X: e.clientX + sLeft - cLeft,
Y: e.clientY + sTop - cTop
}
}
// 获取元素样式
function getStyles(elem, prop) {
if (window.getComputedStyle) {
if (prop) {
return window.getComputedStyle(elem, null)[prop];
} else {
return window.getComputedStyle(elem, null);
}
} else {
if (prop) {
return window.currentStyle(elem, null)[prop];
} else {
return window.currentStyle(elem, null);
}
}
}
// 取消冒泡
function cancelBubble(e) {
var e = e || window.event;
if (e.stopPropagation) {
e.stopPropagation();
} else {
e.cancelBubble = true;
}
}
// 阻止默认事件
function preventDefaultEvent(e) {
var e = e || window.event;
if (e.preventDefaultEvent) {
e.preventDefaultEvent();
} else {
e.returnValue = false;
}
}
var box = document.getElementsByClassName("box")[0];
drag(box);
function drag(elem) {
var x,
y;
addEvent(elem, 'mousedown', function(e) {
var e = e || window.event;
x = pagePos(e).X - parseInt(getStyles(elem, 'left'));
y = pagePos(e).Y - parseInt(getStyles(elem, 'top'));
addEvent(document, 'mousemove', mouseMove);
addEvent(document, 'mouseup', mouseUp);
cancelBubble(e);
preventDefaultEvent(e);
})
function mouseMove(e) {
var e = e || window.event;
elem.style.left = pagePos(e).X - x + 'px';
elem.style.top = pagePos(e).Y - y + 'px';
}
function mouseUp(e) {
var e = e || window.event;
removeEvent(document, 'mousemove', mouseMove);
removeEvent(document, 'mouseup', mouseUp);
}
}
</script>
</body>
</html>