JS小功能(onmousedown实现鼠标拖拽div移动)

效果


image.png
image.png
image.png
思路:
利用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>


  
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,076评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,658评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,732评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,493评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,591评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,598评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,601评论 3 415
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,348评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,797评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,114评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,278评论 1 344
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,953评论 5 339
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,585评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,202评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,442评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,180评论 2 367
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,139评论 2 352