先上图,复制走就可以看效果了
<!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>原生JS复习</title>
</head>
<style>
* {
margin: 0;
padding: 0
}
.box {
width: 400px;
height: 400px;
border: 1px solid red;
position: absolute;
left: 20px;
top: 20px;
}
.box1 {
width: 200px;
height: 200px;
border: 1px solid red;
position: absolute;
left: 20px;
top: 20px;
}
.box2 {
width: 100px;
height: 100px;
border: 1px solid red;
position: absolute;
left: 20px;
top: 20px;
}
.wrap {
width: 1000px;
height: 800px;
border: 1px solid blue;
position: relative;
}
img {
position: absolute;
width: 50%;
height: 50%;
user-select: none;
}
</style>
<body style="border:1px solid red;width:100%;height:100%">
<div class="wrap draggable">
<div class="box draggable">
<div class="box1 draggable">
<div class="box2 draggable"></div>
</div>
</div>
<div class="box draggable">
<div class="box1 draggable">
<div class="box2 draggable"></div>
</div>
</div>
<div class="box draggable">
<div class="box1 draggable">
<div class="box2 draggable"></div>
</div>
</div>
<div class="box draggable">
<div class="box1 draggable">
<div class="box2 draggable">
</div>
</div>
<img src="https://ss0.baidu.com/6ONWsjip0QIZ8tyhnq/it/u=2247692397,1189743173&fm=5" class="draggable">
</div>
</div>
<script>
//事件工具函数
var EventUtil = {
//添加事件监听
addHandler: function(element, type, handler) {
if (element.addEventListener) {
element.addEventListener(type, handler, false);
} else if (element.attachEvent) {
element.attachEvent("on" + type, handler);
} else {
element["on" + type] = handler;
}
},
//移除事件监听
removeHandler: function(element, type, handler) {
if (element.removeEventListener) {
element.removeEventListener(type, handler, false);
} else if (element.detachEvent) {
element.detachEvent("on" + type, handler);
} else {
element["on" + type] = null;
}
},
//获取事件对象
getEvent: function(event) {
return event ? event : window.event;
},
//获取事件元素
getTarget: function(event) {
return event.target || event.srcElement;
},
//取消默认事件
preventDefault: function(event) {
if (event.preventDefault) {
event.preventDefault();
} else {
event.returnValue = false;
}
},
//取消冒泡
stopPropagation: function(event) {
if (event.stopPropagation) {
event.stopPropagation();
} else {
event.cancelBubble = true;
}
}
};
//XHR兼容写法
function createXHR() {
if (typeof XMLHttpRequest != "undefined") {
return new XMLHttpRequest();
} else if (typeof ActiveXObject != "undefined") {
if (typeof arguments.callee.activeXString != "string") {
var versions = ["MSXML2.XMLHttp.6.0", "MSXML2.XMLHttp.3.0", "MSXML2.XMLHttp"],
i, len;
for (i = 0, len = versions.length; i < len; i++) {
try {
new ActiveXObject(versions[i]);
arguments.callee.activeXString = versions[i];
break;
} catch (ex) { //跳过
}
}
}
return new ActiveXObject(arguments.callee.activeXString);
} else {
throw new Error("No XHR object available.");
}
}
//检测类型
function isArray(value) {
return Object.prototype.toString.call(value) == "[object Array]";
}
function isFunction(value) {
return Object.prototype.toString.call(value) == "[object Function]";
}
function isRegExp(value) {
return Object.prototype.toString.call(value) == "[object RegExp]";
}
var isNativeJSON = window.JSON && Object.prototype.toString.call(JSON) == "[object JSON]";
// 拖拽函数
var DragDrop = function() {
var dragging = null;
var left = 0
var top = 0
var toBodyPosition = null
//找到父级元素相对body的位置
function get2BodyPosition(element) {
let left = 0
let top = 0
let parent = element.offsetParent
while (parent && parent.tagName != 'BODY') {
left += parent.offsetLeft
top += parent.offsetTop
parent = parent.offsetParent
}
return {
left,
top
}
}
function handleEvent(event) {
//获取事件和目标
event = EventUtil.getEvent(event);
var target = EventUtil.getTarget(event);
//确定事件类型
switch (event.type) {
case "mousedown":
if (target.className.indexOf("draggable") > -1) {
dragging = target;
dragging.style.cursor = 'move'
//获取鼠标点击位置相对点击元素的位置并记住
left = event.offsetX
top = event.offsetY
//获取鼠标点击元素的父元素相对BODY的位置
toBodyPosition = get2BodyPosition(dragging)
}
break;
case "mousemove":
if (dragging !== null) {
if (dragging.tagName == 'IMG') {
EventUtil.preventDefault(event)
}
let L = event.pageX - toBodyPosition.left - left
let R = event.pageY - toBodyPosition.top - top
//确保不出边框
L = L >= 0 ? L : 0
R = R >= 0 ? R : 0
let parentNode = dragging.offsetParent
if (L >= parentNode.offsetWidth - dragging.offsetWidth) {
L = parentNode.offsetWidth - dragging.offsetWidth
}
if (R >= parentNode.offsetHeight - dragging.offsetHeight) {
R = parentNode.offsetHeight - dragging.offsetHeight
}
//指定位置
dragging.style.left = L + "px";
dragging.style.top = R + "px";
}
break;
case "mouseup":
dragging.style.cursor = 'default'
dragging = null;
break;
}
};
//公共接口
return {
enable: function() {
EventUtil.addHandler(document, "mousedown", handleEvent);
EventUtil.addHandler(document, "mousemove", handleEvent);
EventUtil.addHandler(document, "mouseup", handleEvent);
},
disable: function() {
EventUtil.removeHandler(document, "mousedown", handleEvent);
EventUtil.removeHandler(document, "mousemove", handleEvent);
EventUtil.removeHandler(document, "mouseup", handleEvent);
}
}
}();
DragDrop.enable()
</script>
</body>
</html>