效果
思路:
利用onmousedown事件实现拖拽。首先获得鼠标横坐标点和纵坐标点到div的距离,然后当鼠标移动后再用可视区的距离减去横纵坐标与div的距离。然后在判断不让DIV移出可视区,然后再赋予DIV的位置。最后关闭鼠标onmouseup事件。
Fiish event事件的拖拽和编辑功能
data(){
return{
currentDOM: '',
parentDom: '',
childDom: '',
contenteditable: 'false',
}
}
//鼠标移入事件
mouseover(event) {
let that = this;
that.currentDOM = event.target;
var parentclassName = that.currentDOM.parentNode.getAttribute('class');
if (parentclassName != null) {
if (parentclassName.indexOf('Report') != -1) { //在span范围内
that.childDom = that.currentDOM;
that.childDom.style.cursor = 'pointer'
} else { //不在span范围内
that.childDom = null;
}
}
//console.log("鼠标移入事件")
},
//鼠落下事件
doubleHtml(event) {
//console.log("鼠标落下事件")
document.addEventListener('onmousedown', this.clickDown);
document.addEventListener('dblclick', this.clickPoint);
let that = this;
//此处为单击事件要执行的代码
that.currentDOM = event.target;
that.childDom.setAttribute("contenteditable", 'true')
that.childDom.parentNode.removeAttribute('contenteditable')
var parentclassName = that.childDom.parentNode.getAttribute('class');
let mBounds = that.mouseBounds(
event,
that.childDom.getClientRects()[0],
that.childDom.parentNode.getClientRects()[0]
);
if (parentclassName != null) {
if (parentclassName.indexOf('Report') != -1) {
that.childDom.style.position = 'relative';
that.childDom.style.display = ' inline-block';
that.childDom.parentNode.setAttribute('valign', 'top');
document.onmousemove = function (event) {
let pt = that.calcPositon(event, mBounds);
that.childDom.style.left = pt.left + 'px';
that.childDom.style.top = pt.top + 'px';
that.childDom.style.opacity = 0.8;
that.childDom.style.cursor = 'pointer'
};
document.onmouseup = function () {
document.onmousemove = null;
document.onmousedown = null;
//document.onmouseup = null;k
if (that.childDom.style == null){
} else {
that.childDom.style.opacity = 1;
that.childDom.style.cursor = 'default'
that.childDom.setAttribute("contenteditable", 'true')
//console.log('鼠标弹起')
}
}
return false; //chrome,ff,ie9
} else if (parentclassName.indexOf('Report') == null) {
return false;
} else {
return false;
}
} else {
return false;
}
},
mouseBounds(pt, compRact, containerRact) {
let bounds = {
left: containerRact.left + (pt.x - compRact.left),
right: containerRact.right - (compRact.right - pt.x),
top: containerRact.top + (pt.y - compRact.top),
bottom: containerRact.bottom - (compRact.bottom - pt.y),
offsetX: containerRact.left + (pt.x - compRact.left),
offsetY: containerRact.top + (pt.y - compRact.top)
};
return bounds;
},
calcPositon(pt, bounds) {
let left;
if (pt.x > bounds.left && pt.x < bounds.right) {
left = pt.x;
} else if (pt.x >= bounds.right) {
left = bounds.right
} else {
left = bounds.left
}
left = left - bounds.offsetX;
const top =
(pt.y > bounds.top && pt.y < bounds.bottom
? pt.y
: pt.y >= bounds.bottom
? bounds.bottom
: bounds.top) - bounds.offsetY;
return {left, top}
},
第一种
第二种
function small_down(e) {
var obig = document.getElementById("big");
var osmall = document.getElementById("small");
var e = e || window.event;
/*用于保存小的div拖拽前的坐标*/
osmall.startX = e.clientX - osmall.offsetLeft;
osmall.startY = e.clientY - osmall.offsetTop;
/*鼠标的移动事件*/
document.onmousemove = function (e) {
var e = e || window.event;
osmall.style.left = e.clientX - osmall.startX + "px";
osmall.style.top = e.clientY - osmall.startY + "px";
/*对于大的DIV四个边界的判断*/
if (e.clientX - osmall.startX <= 0) {
osmall.style.left = 0 + "px";
}
if (e.clientY - osmall.startY <= 0) {
osmall.style.top = 0 + "px";
}
if (e.clientX - osmall.startX >= 250) {
osmall.style.left = 250 + "px";
}
if (e.clientY - osmall.startY >= 250) {
osmall.style.top = 250 + "px";
}
};
/*鼠标的抬起事件,终止拖动*/
document.onmouseup = function () {
document.onmousemove = null;
document.onmouseup = null;
};
}
#big {
margin:100px;
border:1px solid #FF3300;
width:300px;
height:300px;
position:relative;
}
#small {
background:#99CC00;
width:50px;
height:50px;
position:absolute;
cursor:pointer;
}
链接:https://www.jianshu.com/p/36f3ae3d0bcc
第三种
Document
第四种
拖拽效果限制范围-蚂蚁部落
以上代码实现了拖拽效果,并且将拖拽返回限定在红色的div之内,下面就介绍一下实现过程:
一.实现原理:
原理其实非常的简单,绿色的div定位方式为绝对定位,它的父元素的定位方式为相对定位,那么绿色div的定位参考对象就是红色的div,当进行拖动的时候就会判断元素的left和top属性值是否使绿色div超出了红色父元素的边界,如果超出就将他们的top和left属性值设置为边界临界状态,这样就实现了将绿色div限定于红色div之内。
二.代码注释:
1.window.onload=function(){},当文档内容完全加载完成之后再去执行函数中的代码。
2.var obox=document.getElementById("box"),获取id属性值为box的元素。
3.var odrag=document.getElementById("drag"),获取id属性值为drag的元素。
4.var isDrag=false,此变量用于标识div是否可以被拖动。
5.var x,y,用于存放鼠标指针距离要拖动div的左边缘和上边缘的距离。
6.odrag.onmousedown=down,为绿色div注册onmousedown事件处理函数。
7.document.onmousemove=move,为document对象注册onmousemove事件处理函数,之所以没有直接给odrag注册,是因为利用事件冒泡可以防止鼠标滑出div导致拖动失效现象。
8.document.onmouseup=up,为document对象注册onmouseup事件处理函数,同样利用了事件冒泡。
9.function down(ev){},onmousedown事件处理函数,ev为事件对象。
10.var ev=window.event||ev,为了兼容各主要浏览器。
11.x=ev.clientX-this.offsetLeft,获取鼠标指针距离div左边缘的距离。
12.y=ev.clientY-this.offsetTop,获取鼠标指针距离div上边缘的距离。
13.this.style.cursor="move",将鼠标的指针形状设置为十字型。
14.isDrag=true,将isDrag值设置为true,也就是可以拖动。
15.function move(ev){},onmousemove事件处理函数,ev为事件对象。
16.if(isDrag),判断是否可以拖动。
17.odrag.style.left=(ev.clientX-x)+"px",设置div的lef属性值。
18.odrag.style.top=(ev.clientY-x)+"px",设置div的top属性值。
19.if(parseInt(odrag.style.left)<0),如果小于0,说明超出左边缘。
20.odrag.style.left=0,将left属性值设置为0,那么恰好在父元素的左边缘。
21.if(parseInt(odrag.style.top)<0),这个原理同上,只是方位不同,这里不多介绍了。
22.if(parseInt(odrag.style.left)>obox.clientWidth-odrag.clientWidth),用于判断绿色div的left属性值是否大于父元素的宽度减去绿色div的宽度,也就是说是否超过了父元素的右边界。
22.odrag.style.left=(obox.clientWidth-odrag.clientWidth)+"px",将绿色div的left属性值设置为obox.clientWidth-odrag.clientWidth,也就是说绿色div的右边界恰好在父div的右边缘。
23,.if(parseInt(odrag.style.top)>obox.clientHeight-odrag.clientHeight),原理同上,这里不多介绍了。
24.function up(){},onmouseup事件处理函数。
25.isDrag=false,设置为不能拖动。
第五种
/**
* 鼠标可以移动的范围
* pt:鼠标按下的点
* compRact:要移动组件的矩形对象
* containerRact:容器的矩形对象
* return 的范围为浏览器窗口中的范围
*/
mouseBounds(pt, compRact, containerRact){
return {
left: containerRact.left,
right: containerRact.right - (compRact.right - pt.x),
top: containerRact.top ,
height:containerRact.height,
bottom: containerRact.bottom - (compRact.bottom - pt.y),
offsetX: containerRact.left + (pt.x - compRact.left),
offsetY: containerRact.top + (pt.y - compRact.top),
}
},
handleHtml($event){
$event.target.className = 'dragMove';
$event.target.style.position = 'absolute';
var child = $event.target;
var clickParent = child.parentNode;
console.log(clickParent.offsetHeight,123456888888888)
var mBounds = this.mouseBounds($event,child.getClientRects()[0],clickParent.getClientRects()[0])
console.log(mBounds.height,321654888888888888)
debugger;
child.onmousedown = function (e) {
var ev = e || event; //兼容IE浏览器和非ie浏览器
var left = ev.clientX - child.offsetLeft,
top = ev.clientY - child.offsetTop;
console.log(ev.clientX,child.offsetLeft,ev.clientY,child.offsetTop,8888888888888)
console.log(ev.clientX,clickParent.offsetLeft,ev.clientY,clickParent.offsetTop)
document.onmousemove = function(e) {
var ev = e || event;
var leftW = ev.clientX - left; //获取span左边的距离
var topH = ev.clientY - top; //获取span上边的距离
//let pt = calcPositon(ev, mBounds)
var w = window.innerWidth
|| document.documentElement.clientWidth
|| document.body.clientWidth;
console.log(ev,w,99999999999)
console.log(leftW,topH,6666666666)
//左边不能超出
if (leftW + w/2 < mBounds.left) {
leftW = mBounds.left - w/2;
}
//上边不能超出
if (topH < mBounds.top) {
topH = mBounds.top;
}
//右边不能超出
if (leftW > mBounds.right - w/2 - 7) {
leftW = mBounds.right - w/2 - 7;
}
//下边不能超出
if (topH > mBounds.top + mBounds.height -25) {
topH = mBounds.top + mBounds.height -25;
}
child.style.left = leftW + 'px';
child.style.top = topH + 'px';
}
document.onmouseup = function(e) {
document.onmousemove = null;
document.onmouseup = null;
}
return false;
}
},