<style>
* {
margin: 0;
padding: 0;
}
body {
height: 5000px;
}
.box {
800px;
height: 800px;
border: 10px solid #000;
margin: 30px auto;
position: relative;
}
.inner {
100px;
height: 100px;
background: pink;
position: absolute;
top: 0;
left: 0;
}
</style>
</head>
<body>
<div class="box">
<div class="inner"></div>
</div>
<script src="./tools.js"></script>
<script>
// 粉色div在 父级div 范围内拖拽,不能移动出div范围
// 1,先实现拖拽
// 获取标签对象
var oBox = document.querySelector('.box');
var oInner = document.querySelector('.inner');
// 获取父级标签,margin-left 和 border-left 占位
// 当前不是通过 style 获取样式属性
// 是通过 getComputedStyle 获取样式属性
// 支持 marginLeft 和 margin-left
// margin-left 属性值
var ml = parseInt(myGetStyle(oBox, 'margin-left'));
// margin-top 属性值
var mt = parseInt(myGetStyle(oBox, 'marginTop'));
// border-left-width 宽度
var bl = parseInt(myGetStyle(oBox, 'border-left-width'));
// border-top-width 宽度
var bt = parseInt(myGetStyle(oBox, 'border-top-width'));
// 获取inner, div标签的相关数据
var hs = oInner.offsetHeight;
var ws = oInner.offsetWidth;
// 获取oBox, div标签的相关数据
var hf = oBox.clientHeight;
var wf = oBox.clientWidth;
// 鼠标按下,给鼠标移动添加 事件处理函数
oInner.addEventListener('mousedown', function () {
document.addEventListener('mousemove', myMove);
})
// 鼠标抬起,给鼠标移动删除 事件处理函数
document.addEventListener('mouseup', function () {
document.removeEventListener('mousemove', myMove);
})
function myMove(e) {
e = e || window.event;
// 获取的是页面左上角到鼠标的定位
var t = e.pageY;
var l = e.pageX;
// 赋值时,left 定位需要减去 父级元素 左侧margin-left占位 左侧边框线占位
// 赋值时,top 定位需要减去 父级元素 上侧margin-top占位 上侧边框线占位
// 如果需要div中心位置和鼠标位置重合
// 需要减去占位的一半
t = t - mt - bt - hs/2;
l = l - ml - bl - ws/2;
// 设定极值范围
// 最小值坐标就是 0 0 不能是负数
// 最大值坐标就是 父级div宽高 - 子级div宽高
if(t < 0){
t = 0;
}
if(l < 0){
l = 0;
}
if(t > hf - hs){
t = hf - hs;
}
if(l > wf - ws){
l = wf - ws;
}
oInner.style.top = t + 'px';
oInner.style.left = l + 'px';
}
// 总结:
// 1,因为页面有可能滚动,获取的数据必须是针对页面的坐标
// 获取鼠标坐标,需要是 e.pageX e.pageY
// 2,需要提前获取到标签的相关数据
// 父级 : 内容(宽高) + padding 的占位
// 左 上 的 margin 和 border 占位
// 子级 : 内容(宽高) + padding + border 的占位
// 内容(宽高) + padding 的占位
// 最好定义在 函数值外,先获取好数据
// 3, 除了 触发 鼠标按下事件效果,必须在 inner,div 范围内
// 其他 事件的触发,都有可能在 inner,div范围外,必须要给 document 做绑定
// 4, mousemove 必须以函数名称的形式,绑定事件处理函数
// 当 鼠标抬起时,才能执行删除事件处理函数
// 5, left定位数值 :
// 鼠标坐标 - oBox,div的左外边距 - oBox,div的左边框宽度 - inner,div宽度的一半
// 6, top定位数值:
// 鼠标坐标 - oBox,div的上外边距 - oBox,div的上边框宽度 - inner,div高度的一半
// 7, 设定极值:
// 当前定位使用的是绝对定位 absolute
// 最小值 : 0 0
// 最大值 : oBox,div,内容(宽高)+padding占位 - oInner,div, 内容(宽高)+padding+border占位
获取鼠标的坐标, offset client page
offset : 拖拽时,因为坐标原点的改变,造成div,来回闪烁
点击时可以使用
client : div 使用 fixed 固定定位时 , 使用 client
都是 视窗窗口的左上角
page :div 使用 absolute 绝对定位
定位原点的左上角是 父级标签的左上角
与视窗窗口的左上角不一定重合
只能使用 page 坐标