效果
image.png
image.png
image.png
思路:
利用onmousedown事件實(shí)現(xiàn)拖拽峻厚。首先獲得鼠標(biāo)橫坐標(biāo)點(diǎn)和縱坐標(biāo)點(diǎn)到div的距離,然后當(dāng)鼠標(biāo)移動后再用可視區(qū)的距離減去橫縱坐標(biāo)與div的距離甘磨。然后在判斷不讓DIV移出可視區(qū)泞坦,然后再賦予DIV的位置。最后關(guān)閉鼠標(biāo)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',
}
}
//鼠標(biāo)移入事件
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范圍內(nèi)
that.childDom = that.currentDOM;
that.childDom.style.cursor = 'pointer'
} else { //不在span范圍內(nèi)
that.childDom = null;
}
}
//console.log("鼠標(biāo)移入事件")
},
//鼠落下事件
doubleHtml(event) {
//console.log("鼠標(biāo)落下事件")
document.addEventListener('onmousedown', this.clickDown);
document.addEventListener('dblclick', this.clickPoint);
let that = this;
//此處為單擊事件要執(zhí)行的代碼
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('鼠標(biāo)彈起')
}
}
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) { //鼠標(biāo)按下
var oEvent = ev || event; //判斷瀏覽器兼容
disX = oEvent.clientX - div1.offsetLeft; //鼠標(biāo)橫坐標(biāo)點(diǎn)到div的offsetLeft距離
disY = oEvent.clientY - div1.offsetTop; //鼠標(biāo)縱坐標(biāo)點(diǎn)到div的offsetTop距離
document.onmousemove = function (ev) { //鼠標(biāo)移動
var oEvent = ev || event;
var l = oEvent.clientX - disX; //獲取div左邊的距離
var t = oEvent.clientY - disY; //獲取div上邊的距離
if (l < 0) { //判斷div的可視區(qū),為避免DIV失去鼠標(biāo)點(diǎn)
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 () { //當(dāng)鼠標(biāo)松開后關(guān)閉移動事件和自身事件
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拖拽前的坐標(biāo)*/
osmall.startX = e.clientX - osmall.offsetLeft;
osmall.startY = e.clientY - osmall.offsetTop;
/*鼠標(biāo)的移動事件*/
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";
}
};
/*鼠標(biāo)的抬起事件,終止拖動*/
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;
}
鏈接:http://www.reibang.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 }
}
/**
* 鼠標(biāo)可以移動的范圍
* pt:鼠標(biāo)按下的點(diǎn)
* 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>
以上代碼實(shí)現(xiàn)了拖拽效果蔗崎,并且將拖拽返回限定在紅色的div之內(nèi),下面就介紹一下實(shí)現(xiàn)過程:
一.實(shí)現(xiàn)原理:
原理其實(shí)非常的簡單扰藕,綠色的div定位方式為絕對定位缓苛,它的父元素的定位方式為相對定位,那么綠色div的定位參考對象就是紅色的div邓深,當(dāng)進(jìn)行拖動的時候就會判斷元素的left和top屬性值是否使綠色div超出了紅色父元素的邊界未桥,如果超出就將他們的top和left屬性值設(shè)置為邊界臨界狀態(tài),這樣就實(shí)現(xiàn)了將綠色div限定于紅色div之內(nèi)芥备。
二.代碼注釋:
1.window.onload=function(){},當(dāng)文檔內(nèi)容完全加載完成之后再去執(zhí)行函數(shù)中的代碼冬耿。
2.var obox=document.getElementById("box"),獲取id屬性值為box的元素萌壳。
3.var odrag=document.getElementById("drag")亦镶,獲取id屬性值為drag的元素日月。
4.var isDrag=false,此變量用于標(biāo)識div是否可以被拖動缤骨。
5.var x,y爱咬,用于存放鼠標(biāo)指針距離要拖動div的左邊緣和上邊緣的距離。
6.odrag.onmousedown=down绊起,為綠色div注冊onmousedown事件處理函數(shù)精拟。
7.document.onmousemove=move,為document對象注冊onmousemove事件處理函數(shù)虱歪,之所以沒有直接給odrag注冊蜂绎,是因?yàn)槔檬录芭菘梢苑乐故髽?biāo)滑出div導(dǎo)致拖動失效現(xiàn)象。
8.document.onmouseup=up笋鄙,為document對象注冊onmouseup事件處理函數(shù)师枣,同樣利用了事件冒泡。
9.function down(ev){},onmousedown事件處理函數(shù)局装,ev為事件對象坛吁。
10.var ev=window.event||ev,為了兼容各主要瀏覽器铐尚。
11.x=ev.clientX-this.offsetLeft拨脉,獲取鼠標(biāo)指針距離div左邊緣的距離。
12.y=ev.clientY-this.offsetTop宣增,獲取鼠標(biāo)指針距離div上邊緣的距離玫膀。
13.this.style.cursor="move",將鼠標(biāo)的指針形狀設(shè)置為十字型爹脾。
14.isDrag=true帖旨,將isDrag值設(shè)置為true,也就是可以拖動灵妨。
15.function move(ev){}解阅,onmousemove事件處理函數(shù),ev為事件對象泌霍。
16.if(isDrag)货抄,判斷是否可以拖動。
17.odrag.style.left=(ev.clientX-x)+"px"朱转,設(shè)置div的lef屬性值蟹地。
18.odrag.style.top=(ev.clientY-x)+"px",設(shè)置div的top屬性值藤为。
19.if(parseInt(odrag.style.left)<0)怪与,如果小于0,說明超出左邊緣缅疟。
20.odrag.style.left=0分别,將left屬性值設(shè)置為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屬性值設(shè)置為obox.clientWidth-odrag.clientWidth,也就是說綠色div的右邊界恰好在父div的右邊緣曲管。
23,.if(parseInt(odrag.style.top)>obox.clientHeight-odrag.clientHeight),原理同上却邓,這里不多介紹了。
24.function up(){},onmouseup事件處理函數(shù)院水。
25.isDrag=false腊徙,設(shè)置為不能拖動。
第五種
/**
* 鼠標(biāo)可以移動的范圍
* pt:鼠標(biāo)按下的點(diǎn)
* 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>