JavaScript实现图片和div拖拽

今天需要一个图片拖拽功能,代码量小,就用原生JavaScript写吧!

我们拖拽的动作由这么一组流程:
1、鼠标在图片上按下左键————>2、拖动鼠标移动————>3、松开鼠标左键。

看一下原理图


拖拽原理图1

1、鼠标在图片上按下左键
这个环节,我们需要获取:
鼠标按下时的x、y坐标,设置为X和Y。
图片距离浏览器窗口顶部和左边的距离,设置为boxT和boxL。
这时候,我们还需要计算鼠标在图片上,按下时的坐标距离图片左边和顶部的距离,设置为disL和disT。
如图所示:


X-boxL=disL

为什么要设置disL和disT呢?
因为我们在进行拖拽时,需要实时获取图片距离浏览器窗口顶部和左边的距离,这个距离是动态的,是你鼠标的x、y坐标,减去坐标距离图片左边和顶部的距离disL和disT,得到动态的数值,赋值给图片的left和top。这样才能实现拖动效果。


拖动后

实际上拖拽就是不停的改变图片的left和top值。
下面是代码实现,js代码有注释。

html code

<img src="https://placem.at/things?w=100&h=100&random=1" alt="" class="img-thumbnail" id="oBox1" />
<div class="alert alert-primary" id="oBox2"></div>

css code


#oBox1,#oBox2{position: absolute;cursor: pointer;}
#oBox1 {left: 50px; top: 100px;}
#oBox2 {left: 200px;top: 100px;}

js code

//封装了一个取消默认事件的函数,用来兼容老IE
function cancelHandler(event){
  if (event.preventDefault) {
    event.preventDefault();
  } else {
    event.returnValue = false;
  }
  }
 
 function bindEvent(_id) {
var ele = document.getElementById(_id);
//设置鼠标落下时的x、y坐标为X和Y,盒子的left和top值存为boxL和boxT,鼠标落下时的点距离盒子左边和上边的距离存为disL和disT
let X, L, boxL, boxT, disL, disT, drag = false;
ele.onmousedown = function(e) {
    drag = true;
    var e = e || window.event; //兼容ie
    X = e.clientX;
    Y = e.clientY;
    boxL = ele.offsetLeft;
    boxT = ele.offsetTop;
    disL = X - boxL;
    disT = Y - boxT;
    cancelHandler(e);
}
document.onmousemove = function(e) {
    var e = e || window.event;
    if (drag) {
        ele.style.left = e.clientX - disL + 'px';
        ele.style.top = e.clientY - disT + 'px';
    }
}
ele.onmouseup = function() {
    drag = false;
}
}
bindEvent('oBox1');
//bindEvent('oBox2');

思路理清了,按照思路,代码也写好了,那么.,是否还能对代码继续优化呢?
当然可以,一点小优化

var disL, disT, drag = false;
ele.onmousedown = function(e) {
    drag = true;
    var e = e || window.event; //兼容ie
    disL = e.clientX - ele.offsetLeft;
    disT = e.clientY - ele.offsetTop;
    cancelHandler(e);
}

另外,我还写了一个通过拖动div到另一个div上,改变背景颜色的实例

html code

<body id="bg">
        <div class="container">
<div class="alert alert-info rounded-circle" id="oBox5"></div>
<div class="alert alert-warning rounded-circle" id="oBox4"></div>
        </div>
    </body>

css同样引用了bootstrap4,其他css:

#oBox1,#oBox2,#oBox3,#oBox4,#oBox5 {position: absolute;cursor: pointer;}
#oBox4 {width: 100px;height: 100px; top:250px;left: 105px;}
#oBox5 {width: 100px;height: 100px; top:250px;left: 250px;}
#bg{background-color: rgb(43, 62, 80);}

js code

    function bindEvent2(_id1,_id2){
    let ele1 = document.getElementById(_id1),
        ele2 = document.getElementById(_id2),
        ele1W = ele1.offsetWidth,
        ele1H = ele1.offsetHeight,
        ele2L = ele2.offsetLeft,
        ele2T = ele2.offsetTop,
        ele1L, ele1T, coverH, coverW, X, L, boxL, boxT,boxW,boxH, disL, disT, drag = false;
    // let ele1T = ele1.offsetTop,
    //  ele1L = ele1.offsetLeft;
    ele1.addEventListener('mousedown',function(e){
        drag = true;
        var e = e || window.event; //兼容ie
        disL = e.clientX - ele1.offsetLeft;
        disT = e.clientY - ele1.offsetTop;
        cancelHandler(e);
    },false);
    document.addEventListener('mousemove',function(e){
        var e = e || window.event;
        if (drag) {
            ele1.style.left = e.clientX - disL + 'px';
            ele1.style.top = e.clientY - disT + 'px';
            ele1L = ele1.offsetLeft;
            ele1T = ele1.offsetTop;
            if ((ele1L + ele1W >= ele2L)&& (ele1L <= ele2L)) {//重叠开始
                coverW = ele1L+ele1W-ele2L;
                //console.log('左边进'+coverW);
            }else if((ele2L + ele1W >ele1L)&&(ele2L + ele1W < ele1L + ele1W)){
                coverW = ele2L + ele1W - ele1L;
                //console.log('右边出' +coverW);
            }
            if ((ele1T + ele1H >= ele2T)&&(ele1T<=ele2T)) {
                coverH = ele1T + ele1H - ele2T;
                //console.log('上边进' + coverH);
            } else if((ele2T + ele1H >= ele1T)&&(ele2T + ele1H < ele1T + ele1H)){
            coverH = ele2T + ele1H - ele1T;
            //console.log('下边出' +coverH);   
            }
            console.log(coverH*coverW);
            bg.style.backgroundColor = 'rgb(43,'+ coverH +','+ coverW+')';
        }
    },false);
    ele1.addEventListener('mouseup',function(){
        drag = false;
    },false)
    }
    bindEvent2('oBox4','oBox5');

最后看一下效果


拖动div控制背景颜色

欢迎大家提出优化代码的建议.

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

推荐阅读更多精彩内容

  •   JavaScript 与 HTML 之间的交互是通过事件实现的。   事件,就是文档或浏览器窗口中发生的一些特...
    霜天晓阅读 3,426评论 1 11
  • 开始iOS 7中自动布局教程(一) 发布于:2013-12-03 13:53阅读数:86977 到目前为止,如果你...
    谁的青春不迷茫阅读 913评论 0 2
  • 成为一个 多才多艺 受人尊敬 令人羡慕 让人喜爱 的人
    王博_c1ce阅读 150评论 0 0
  • 烦的时候就给自己几分钟相信这几分钟里你会做出正确的选择 我现在的文章以自己的心理感受为主,语言偏幼稚,但我还是厚着...
    刺猬_君阅读 195评论 0 0
  • 《爱说“所以”的挖土机》是青豆童书馆出版的一本绘本。全书以孩子的语言讲解了挖土机的工作,满足了孩子们探索世界,探索...
    颜洳碧语阅读 320评论 0 3