效果
思路:
利用onmousedown事件实现拖拽。首先获得鼠标横坐标点和纵坐标点到div的距离,然后当鼠标移动后再用可视区的距离减去横纵坐标与div的距离。然后在判断不让DIV移出可视区,然后再赋予DIV的位置。最后关闭鼠标onmouseup事件。
Fiish event事件的拖拽和编辑功能
<div class="delegationHtml"
@click.stop="handleHtml($event)"
@mousedown.stop="doubleHtml($event)"
@mouseover.stop="mouseover($event)"
ref="getDelegationHtml">
<div id="prinMe" v-html="this.delegationHtml" ref="printRef"></div>
</div>
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}
},
第一种
<head runat="server">
<title></title>
<style type="text/css">
#div1
{
width: 200px;
height: 200px;
background: #00FFFF;
position: absolute;
border: 1px solid;
}
</style>
<script type="text/javascript">
window.onload = function () {
var div = document.getElementById('div1');
var disX = 0;
var disY = 0;
document.onmousedown = function (ev) { //鼠标按下
var oEvent = ev || event; //判断浏览器兼容
disX = oEvent.clientX - div1.offsetLeft; //鼠标横坐标点到div的offsetLeft距离
disY = oEvent.clientY - div1.offsetTop; //鼠标纵坐标点到div的offsetTop距离
document.onmousemove = function (ev) { //鼠标移动
var oEvent = ev || event;
var l = oEvent.clientX - disX; //获取div左边的距离
var t = oEvent.clientY - disY; //获取div上边的距离
if (l < 0) { //判断div的可视区,为避免DIV失去鼠标点
l = 0;
}
else if (l > document.documentElement.clientWidth - div.offsetWidth) {
l = document.documentElement.clientWidth - div.offsetWidth;
}
if (t < 0) {
t = 0;
}
else if (t > document.documentElement.clientHeight - div.offsetHeight) {
t = document.documentElement.clientHeight - div.offsetHeight;
}
div.style.left = l + 'px'; //确定DIV的左边位置
div.style.top = t + 'px'; //确定DIV的上边位置
}
document.onmouseup = function () { //当鼠标松开后关闭移动事件和自身事件
document.onmousemove = null;
document.onmouseup = null;
}
return false;
}
}
</script>
</head>
<body>
<div id="div1">
</div>
</body>
第二种
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;
};
}
<div id="big">
<div id="small" onmousedown="small_down(event)"></div>
</div>
#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
第三种
<!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>Document</title>
<style>
html,body,.father {margin: 0;height: 100%;width: 100%;}
body{display: flex;justify-content: center; align-items: center;}
.contain{ position: relative; height: 90%;width: 90%;border: black 1px solid;background-color: rgba(205, 135, 222, 0.767);}
.child {position: absolute;height: 200px;width: 200px;border: black 1px solid;background-color: coral;}
</style>
</head>
<body>
<div class="contain">
<div id="father" class="father">
<div
id="child"
class="child"
onmousedown="mouseDown(event)"
></div>
</div>
</div>
<script>
let child = document.querySelector('#child')
const mouseDown = evt => {
let mBounds = mouseBounds(
evt,
child.getClientRects()[0],
document.querySelector('#father').getClientRects()[0]
)
document.onmousemove = function(ev) {
let pt = calcPositon(ev, mBounds)
child.style.left = pt.left + 'px'
child.style.top = pt.top + 'px'
child.style.opacity = 0.9
child.style.cursor = 'move'
}
document.onmouseup = function() {
document.onmousemove = null
document.onmouseup = null
child.style.opacity = 1
child.style.cursor = 'default'
}
}
const calcPositon = (pt, bounds) => {
const left =
(pt.x > bounds.left && pt.x < bounds.right
? pt.x
: pt.x >= bounds.right
? bounds.right
: bounds.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 }
}
/**
* 鼠标可以移动的范围
* pt:鼠标按下的点
* compRact:要移动组件的矩形对象
* containerRact:容器的矩形对象
* return 的范围为浏览器窗口中的范围
*/
const mouseBounds = (pt, compRact, containerRact) => {
return {
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)
}
}
</script>
</body>
</html>
第四种
<!DOCTYPE html>
<html>
<head>
<meta charset=" utf-8">
<meta name="author" content="http://www.softwhy.com/" />
<title>拖拽效果限制范围-蚂蚁部落</title>
<style type="text/css">
*{
margin:0px;
padding:0px;
}
body{
padding:50px;
}
#box{
width:350px;
height:250px;
background:red;
overflow:hidden;
position:relative;
}
#drag{
width:50px;
height:50px;
background:green;
position:absolute;
}
</style>
<script type="text/javascript">
window.onload=function(){
var obox=document.getElementById("box");
var odrag=document.getElementById("drag");
var isDrag=false;
var x,y;
odrag.onmousedown=down;
document.onmousemove=move;
document.onmouseup=up;
function down(ev){
var ev=window.event||ev;
x=ev.clientX-this.offsetLeft;
y=ev.clientY-this.offsetTop;
this.style.cursor="move";
isDrag=true;
}
function move(ev){
if(isDrag){
var ev=window.event||ev;
odrag.style.left=(ev.clientX-x)+"px";
odrag.style.top=(ev.clientY-x)+"px";
if(parseInt(odrag.style.left)<0){
odrag.style.left=0;
}
if(parseInt(odrag.style.top)<0){
odrag.style.top=0;
}
if(parseInt(odrag.style.left)>obox.clientWidth-odrag.clientWidth){
odrag.style.left=(obox.clientWidth-odrag.clientWidth)+"px";
}
if(parseInt(odrag.style.top)>obox.clientHeight-odrag.clientHeight){
odrag.style.top=(obox.clientHeight-odrag.clientHeight)+"px";
}
}
}
function up(){
isDrag=false;
odrag.style.cursor="pointer";
}
}
</script>
</head>
<body>
<div id="box">
<div id="drag"></div>
</div>
</body>
</html>
以上代码实现了拖拽效果,并且将拖拽返回限定在红色的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;
}
},
<el-dialog
class="s_dialog"
width="50%"
top="0"
:visible.sync="printVisible"
append-to-body
style="overflow-y: hidden;"
>
<li
class="communication"
style="width:100%; height:100%; overflow-y:hidden; border-bottom: 1px solid rgb(243, 243, 243); min-height: 40px;"
>
<div class="orderBookLeft">
<p class="clickSearch">
订舱详情报表
</p>
</div>
<div class="orderBookRight">
<div class="search">
<el-button icon="el-icon-check" round size="small" class="clickams"
v-print="'#prinMe'" @click="print_page">打印
</el-button>
</div>
<div class="search" style="margin-right:20px;">
<el-button icon="el-icon-check" round size="small" class="clickams"
@click="savePrint()">保存
</el-button>
</div>
</div>
</li>
<!-- <div id="prinMe" v-html="this.delegationHtml" class="delegationHtml"></div> -->
<div class="delegationHtml" @mousedown="handleHtml($event)">
<div id="prinMe" v-html="this.delegationHtml" ref="printRef"></div>
</div>
</el-dialog>