[JavaScript学习]用面向对象方法实现拖拽效果

来源:互联网 发布:用手机拍摄淘宝图片 编辑:程序博客网 时间:2024/06/06 08:07

这两天又进一步学习了下JavaScript的面向对象方法,也看了简单的拖拽案例,顺便就尝试自己写写简单的拖拽效果作为练习


目标:实现子DIV在父DIV内的拖拽效果,并且不会突破父DIV边缘,在接近父DIV边缘时,自动吸附到边缘;

想法:

  1. 鼠标在子DIV区域内按下,子DIV获取onclick事件,计算鼠标位置和子DIV左边缘和上边缘的距离;
  2. 鼠标移动,生成一个虚线框的DIV,大小和子DIV一直,左边缘和上边缘与鼠标位置距离和之前测得的鼠标位置与子DIV距离保持一致,跟随鼠标移动,实现拖拽效果;
  3. 若鼠标移动范围超过父DIV边缘,则让虚线框DIV边缘位置与父边框边缘位置保持一致,从而防止突破父DIV边缘;
  4. 当鼠标在父边框内接近父边框边缘一定距离时,将父边框边缘位置赋给虚线框DIV边缘位置,从而实现吸附效果;
  5. 鼠标按键松开,将虚线框DIV的位置信息赋给子DIV,同时消除虚线框DIV。

实现:

HTML:

<!DOCTYPE HTML><html><head><meta charset="utf-8"><title>拖拽</title></head><body><div id="div1"><div id="div2"></div></div></body></html>

CSS:

#div2{width: 80px;height: 80px;background: red;position: absolute;}#div1{width: 400px;height: 400px;background:gray;position: relative;}.box {border: dashed 1px black;position: relative;}

JavaScript:

window.onload = function(){new Drag("div1", "div2", "20");}//拖拽对象构建函数function Drag(fatherId, childId, touchDis){var _this = this;this.touchDis = touchDis;this.disX = 0;this.disY = 0;this.oDiv1 = document.getElementById(fatherId);this.oDiv2 = document.getElementById(childId);//绑定鼠标点下事件处理函数this.oDiv2.onmousedown = function(ev){_this.mouseDown(ev);}}//鼠标点下事件处理函数Drag.prototype.mouseDown = function (ev){var _this = this;var oEvent = ev || event;//保存鼠标位置和子DIV的左边缘与上边缘距离this.disX = oEvent.clientX - this.oDiv2.offsetLeft + document.documentElement.scrollLeft;this.disY = oEvent.clientY - this.oDiv2.offsetTop + document.documentElement.scrollTop;//创建虚线框DIV(oBox),并添加到父DIV的子节点上this.oBox = document.createElement('div');this.oBox.className = 'box';this.oBox.style.width = this.oDiv2.offsetWidth - 2 + 'px';this.oBox.style.height = this.oDiv2.offsetHeight - 2 + 'px';this.oBox.style.left = this.oDiv2.offsetLeft + 'px';this.oBox.style.top = this.oDiv2.offsetTop + 'px';this.oDiv1.appendChild(this.oBox);//简单的鼠标事件捕获兼容处理,并绑定相应的事件处理函数if(this.oDiv2.setCapture){this.oDiv2.onmousemove = function(ev){_this.mouseMove(ev);}this.oDiv2.onmouseup = function(){_this.mouseUp();}this.oDiv2.setCapture();}else{document.onmousemove = function(ev){_this.mouseMove(ev);}document.onmouseup = function(){_this.mouseUp();}}//禁用浏览器默认操作return false;}//鼠标移动事件处理函数Drag.prototype.mouseMove = function (ev){var oEvent = ev || event;var left = oEvent.clientX - this.disX + document.documentElement.scrollLeft;var top = oEvent.clientY - this.disY + document.documentElement.scrollTop;//检测鼠标是否在父DIV内,防止子DIV突破父DIV边界,同时通过判断鼠标和父DIV边缘距离实现边缘吸附效果if(left < this.touchDis){left = 0;}else if(left > this.oDiv1.offsetWidth - this.oDiv2.offsetWidth - this.touchDis){left =  this.oDiv1.offsetWidth - this.oDiv2.offsetWidth;}if(top < this.touchDis){top = 0;}else if(top > this.oDiv1.offsetHeight - this.oDiv2.offsetHeight - this.touchDis){top = this.oDiv1.offsetHeight - this.oDiv2.offsetHeight;};this.oBox.style.left = left + 'px';this.oBox.style.top = top + 'px';};//鼠标松开事件处理函数Drag.prototype.mouseUp = function(){//解除鼠标点下和移动事件处理函数绑定this.onmousemove = null;this.onmousup = null;//奖虚线框DIV位置信息赋给子DIVthis.oDiv2.style.left = this.oBox.offsetLeft + 'px';this.oDiv2.style.top = this.oBox.offsetTop + 'px';//移除虚线框DIVthis.oDiv1.removeChild(this.oBox);if(this.oDiv2.releaseCapture){this.oDiv2.releaseCapture();}};
实现效果如下:传送门

写完后发现其实这样用面向对象方法来实现好像很蛋疼,好像没什么实用性,不过权当练习了……