一. 拖拽至视窗
拖拽的效果 — 边界值
鼠标移动出页面,但是div要留在页面范围内
给定位数值,添加极限范围数值,
定位的最大值,最小值,都要有范围
最小值 : 上 左 都是 0
var oDiv = document.querySelector('div');
var oldTop = window.getComputedStyle(oDiv).top;
var oldLeft = window.getComputedStyle(oDiv).left;
视窗窗口的宽度,高度
var winWidth = document.documentElement.clientWidth;
var winHeight = document.documentElement.clientHeight;
当鼠标按下时,鼠标移动,添加事件
window.onmousedown = function(){
window.onmousemove = function(e){
// 根据 鼠标坐标,根据项目需求,计算定位的数值
var x = e.clientX - oDiv.offsetWidth/2;
var y = e.clientY - oDiv.offsetHeight/2;
// 极限值判断
// 最小值都是 0 0
if(x < 0){
x = 0;
}
if(y < 0){
y = 0;
}
// 最大值 可视窗口的宽度/高度 - ( 标签x轴方向 / y轴方向 最终占位 )
if(x > winWidth - oDiv.offsetWidth){
x = winWidth - oDiv.offsetWidth;
}
if(y > winHeight - oDiv.offsetHeight){
y = winHeight - oDiv.offsetHeight;
}
console.log(x,y);
// 将数值作为标签定位的坐标
oDiv.style.left = x + 'px' ;
oDiv.style.top = y + 'px' ;
}
}
鼠标按键抬起时的移动不会让div跟随
window.onmouseup = function(){
window.onmousemove = null;
}
总结思路
1,一定是 先按下事件,后移动事件 — 先砍头再移尸
2,鼠标抬起,给移动定义事件为null
也可以添加其他操作,例如,让标签回到原位
回到原始位置,需要在程序的起始位置,先记录原始的定位坐标
3,基本思路
(1),在定义函数之外,获取浏览器窗口的宽度,高度
不能带有滚动条
(2),获取鼠标的坐标,根据项目需求,来计算表现定位的数值
鼠标的坐标,要根据实际需求而定,目前使用的是相对可视窗口左上角的定位
项目需求不同,+ / - 的数值也不同
(3),设定极值
最小值为 0 0
最大值为 可视窗口宽度/高度 - 标签X轴/Y轴最终占位
(4),将最终的数据,作为标签定位的坐标
必须拼接px单位
二. 拖拽至边界值
<style>
* {
padding: 0;
margin: 0;
}
body {
height: 5000px;
}
.box {
width: 800px;
height: 800px;
border: 10px solid #000;
margin: 40px auto;
position: relative;
background: skyblue;
}
.inner {
width: 100px;
height: 100px;
background: pink;
position: absolute;
top: 0;
left: 0;
}
</style>
</head>
<body>
<div class="box">
<div class="inner"></div>
</div>
<script>
// 1,获取标签对象
var oBox = document.querySelector('.box');
var oInner = document.querySelector('.inner');
// 2,获取相应的数据
// 获取父级标签的---占位---不包括边框线
var oBoxWidth = oBox.clientWidth;
var oBoxHeight = oBox.clientHeight;
// 获取子级标签的---占位---包括边框线
var oInnerWidth = oInner.offsetWidth;
var oInnerHeight = oInner.offsetHeight;
// 给父级标签添加事件
oInner.onmousedown = function () {
document.onmousemove = function (e) {
// 获取计算,设定子级标签定位的数值
// page坐标 - 外边距 - 边框线 - 子级宽度的一半
var x = e.pageX - oBox.offsetLeft - oBox.clientLeft - oInnerWidth / 2;
var y = e.pageY - oBox.offsetTop - oBox.clientTop - oInnerHeight / 2;
// 设定极限值
// 最小值是0
if (x < 0) {
x = 0;
}
if (y < 0) {
y = 0;
}
// 最大值
// 父级标签占位(没有border) - 移动标签占位(计算border)
if (x > oBoxWidth - oInnerWidth) {
x = oBoxWidth - oInnerWidth;
}
if (y > oBoxHeight - oInnerHeight) {
y = oBoxHeight - oInnerHeight
}
// 将设定好的数值,作为子级标签的定位
oInner.style.left = x + 'px';
oInner.style.top = y + 'px';
}
}
window.onmouseup = function () {
document.onmousemove = null;
}
// 思路步骤和问题
// 1, 事件,到底是绑定给 父级,子级,还是document,还是window
// 事件,取消,到底是通过谁取消
// 没有固定的写法,看你需要的效果
// 还是document和window效果相同,没有区别
// 鼠标按下
// oInner.onmousedown 鼠标在粉色div上,按下鼠标,并且移动鼠标,才会有效果
// oBox.onmousedown 鼠标在蓝色div上,按下鼠标,并且移动鼠标,才会有效果
// window.onmousedown 鼠标在全屏上,按下鼠标,并且移动鼠标,都会有效果
// 鼠标移动
// 最好写成 document.onmousemove / window.onmousemove
// 鼠标可以快速移动,不怕移出粉色div
// 鼠标抬起
// oInner.onmouseup 鼠标在粉色div上抬起,才会执行,标签不跟随移动
// oBox.onmouseup 鼠标在蓝色div上抬起,才会执行,标签不跟随移动
// window.onmouseup 鼠标在整个页面上抬起,都会执行,标签不跟随移动
// 2, 闪烁问题
// 原因: 相对于标签内容的左上角的定位
// 会因为鼠标经过不同的标签对象,获取不同的数据
// 而且JavaScript执行时,有时还会有bug产生
// offsetX offsetY 我们是不推荐使用的
// 解决: 使用 pageX 和 pageY
// 定位: page距离 - 父级标签外边距 - 父级border - 移动标签占位/2(标签中心点和鼠标重合)
// 极值1: 左 上 都是 0
// 极值2: 右 下 父级标签占位(不算border) - 移动标签占位(计算border)