clientX/clientY
鼠标位置相对于当前可视区域的的坐标(不包括已经滚动的)
screenX/screenY
鼠标相对于电脑显示器屏幕的位置
offsetX/offsetY
鼠标位置相对于当前触发事件的块级元素左上角的值(包含边框), 当时 Safari 浏览器不包含
pageX/pageY
鼠标位置相对于当前文档左上角的坐标(包括已经滚动的)
javascript
function getScrollOffset() {
if (window.pageXOffset) {
getScrollOffset = function () {
return {
top: window.pageXOffset,
left: window.pageYOffset,
};
};
} else {
getScrollOffset = function () {
return {
top: document.body.scrollTop + document.documentElement.scrollTop,
left: document.body.scrollLeft + document.documentElement.scrollLeft,
};
};
}
return getScrollOffset();
}
// 请使用这个封装的方法, 让pageX/Y兼容更多的浏览器
function getPagePosition(e) {
var scrollPos = getScrollOffset(),
clientLeft = document.documentElement.clientLeft || 0,
clientTop = document.documentElement.clientTop || 0;
return {
x: e.clientX + scrollPos.left - clientLeft,
y: e.clientY + scrollPos.top - clientTop,
};
}
layerX/layerY(不推荐使用)
这个其实就是 pageX/Y
IE11
及其以下版本, 它的值是 clientX/Y
的值
x/y(不推荐使用)
这个其实就是 clientX
和 clientY
但是 低版本的浏览器可能有兼容性问题, 所以推荐使用 clientX/Y
拖拽方法封装(兼容 IE)
index.html
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>js</title>
<style>
#app {
width: 200px;
height: 200px;
background: #000;
}
</style>
</head>
<body>
<div id="app"></div>
<script src="./js/drag.js"></script>
<script>
var app = document.getElementById("app");
drag({
el: app,
});
</script>
</body>
</html>
js/drag.js
javascript
(function () {
/**
* get pageXOffset
* @returns {Object: {top, left}}
*/
function getScrollOffset() {
if (window.pageXOffset) {
getScrollOffset = function () {
return {
top: window.pageXOffset,
left: window.pageYOffset,
};
};
} else {
getScrollOffset = function () {
return {
top: document.body.scrollTop + document.documentElement.scrollTop,
left: document.body.scrollLeft + document.documentElement.scrollLeft,
};
};
}
return getScrollOffset();
}
/**
* 兼容: 取消冒泡
* @param {Event} e
* @returns
*/
function cancelBubble(e) {
if (e.stopPropagation) {
cancelBubble = function (e) {
e = e || window.event;
return e.stopPropagation();
};
} else {
cancelBubble = function (e) {
e = e || window.event; // window.event 兼容ie8及其以下版本的浏览器
e.cancelBubble = true;
};
}
return cancelBubble(e);
}
/**
* 兼容: 取消浏览器默认事件
* @param {Event} e
* @returns
*/
function preventDefault(e) {
var e = e || widow.event;
if (e.preventDefault) {
// w3c standard
preventDefault = function (e) {
e.preventDefault(e);
};
} else {
// ie: 9/8/7/6
preventDefault = function (e) {
e = e || widow.event;
e.returnValue = false;
};
}
return preventDefault(e);
}
/**
* get PageX
* @param {Event} e event object
* @returns {Object: {x, y}}
*/
function getPagePosition(e) {
var scrollPos = getScrollOffset(),
clientLeft = document.documentElement.clientLeft || 0,
clientTop = document.documentElement.clientTop || 0;
return {
x: e.clientX + scrollPos.left - clientLeft,
y: e.clientY + scrollPos.top - clientTop,
};
}
/**
* 兼容: 添加事件处理函数
* @param {HTMLElement} el 事件源
* @param {String} type 事件类型
* @param {Function} handler
* @returns
*/
function addEvent(el, type, handler) {
if (el.addEventListener) {
addEvent = function (el, type, handler) {
el.addEventListener(type, handler, false);
};
} else if (el.attachEvent) {
addEvent = function (el, type, handler) {
el.attachEvent("on" + type, function () {
handler.call(el);
});
};
} else {
addEvent = function (el, type, handler) {
el["on" + type] = handler;
};
}
return addEvent(el, type, handler); // 只有这一次执行会判断
}
/**
* 兼容: 移除事件处理函数
* @param {HTMLElement} el 事件源
* @param {String} type 事件类型
* @returns
*/
function removeEvent(el, type, handler) {
if (el.removeEventListener) {
removeEvent = function (el, type, handler) {
el.removeEventListener(type, handler);
};
} else if (el.detachEvent) {
removeEvent = function (el, type, handler) {
el.detachEvent("on" + type, handler);
};
} else {
removeEvent = function (el, type, handler) {
el["on" + type] = null;
};
}
return removeEvent(el, type, handler);
}
/**
* 兼容: 获取可视区域大小
* @returns {Object:{width, height}}
*/
function getViewportSize() {
if (window.innerWidth) {
getViewportSize = function () {
return {
width: window.innerWidth,
height: window.innerHeight,
};
};
} else {
getViewportSize = function () {
// ie
var key = document.compatMode === "BackCompat" ? "body" : "documentElement";
return {
width: document[key].clientWidth,
height: document[key].clientHeight,
};
};
}
return getViewportSize();
}
/**
* 让一个元素可以拖动
* @param {object} options 配置选项
* @param {HTMLElement} options.el: 需要被拖动的元素
* @param {Boolean} options.xMoveable: 水平方向是否可以拖动 default: true
* @param {Boolean} options.yMoveable: 垂直方向是否可以拖动 default: true
* @param {Boolean} options.moveOutside: 是否限制移动边界 default: true
*/
function drag(options) {
if (!options || Object.prototype.toString.call(options) !== "[object Object]") {
throw new TypeError("the options must be a object");
}
var el = options.el,
offsetX,
offsetY,
maxWidth,
maxHeight,
xMoveable,
yMoveable,
moveOutside;
if (!el || el.nodeType !== Node.ELEMENT_NODE) {
throw new TypeError("The 'el' must be a HTMLElement");
}
xMoveable = options.xMoveable === false ? false : true;
yMoveable = options.yMoveable === false ? false : true;
moveOutside = options.moveOutside === false ? false : true;
// mouse down
var handleMouseDown = function (e) {
var e = e || window.event;
var target = e.target || e.srcElement;
offsetX = e.offsetX;
offsetY = e.offsetY;
maxWidth = window.innerWidth - target.offsetWidth - 1;
maxHeight = window.innerHeight - target.offsetHeight - 1;
addEvent(document, "mousemove", handleMouseMove);
addEvent(el, "mouseup", handleMouseUp);
};
// mouse move
var handleMouseMove = function (e) {
var e = e || window.event;
var mousePos = getPagePosition(e);
var left, top;
el.style.position = "fixed";
if (xMoveable) {
left = mousePos.x - offsetX;
if (moveOutside) {
left = left >= maxWidth ? maxWidth : left;
left = left <= 0 ? 0 : left;
}
el.style.left = left + "px";
}
if (yMoveable) {
top = mousePos.y - offsetY;
if (moveOutside) {
top = top >= maxHeight ? maxHeight : top;
top = top <= 0 ? 0 : top;
}
el.style.top = top + "px";
}
preventDefault(e);
cancelBubble(e);
};
// mouse up
var handleMouseUp = function (e) {
var e = e || window.event;
removeEvent(document, "mousemove", handleMouseMove);
removeEvent(el, "mouseup", handleMouseUp);
};
addEvent(el, "mousedown", handleMouseDown);
}
window.drag = drag;
})();