今天需要一个图片拖拽功能,代码量小,就用原生JavaScript写吧!
我们拖拽的动作由这么一组流程:
1、鼠标在图片上按下左键————>2、拖动鼠标移动————>3、松开鼠标左键。
看一下原理图
1、鼠标在图片上按下左键
这个环节,我们需要获取:
鼠标按下时的x、y坐标,设置为X和Y。
图片距离浏览器窗口顶部和左边的距离,设置为boxT和boxL。
这时候,我们还需要计算鼠标在图片上,按下时的坐标距离图片左边和顶部的距离,设置为disL和disT。
如图所示:
为什么要设置disL和disT呢?
因为我们在进行拖拽时,需要实时获取图片距离浏览器窗口顶部和左边的距离,这个距离是动态的,是你鼠标的x、y坐标,减去坐标距离图片左边和顶部的距离disL和disT,得到动态的数值,赋值给图片的left和top。这样才能实现拖动效果。
实际上拖拽就是不停的改变图片的left和top值。
下面是代码实现,js代码有注释。
html code
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
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');
最后看一下效果
欢迎大家提出优化代码的建议.