原生js实现拖拽移动与缩放效果

本文实例为大家分享了js实现拖拽移动与缩放效果的具体代码,供大家参考,具体内容如下

效果图如下-实现了简单的拖拽和缩放功能

第一步—简单的拖拽功能

// 创建一个MoveClass构造函数
 function MoveClass(id, options = {}) {
 // 绑定ele属性
 this.ele = document.querySelector(id);

 this.move();
}
// 给MoveClass原型上绑定move方法
 MoveClass.prototype.move = function () {
 // ele的鼠标按下事件调用mousedown
 this.ele.onmousedown = e => {
 // 获取事件对象
 var e = e || window.event;
 // 鼠标按下时,鼠标相对于元素的x坐标
 var x = e.offsetX;
 // 鼠标按下时,鼠标相对于元素的y坐标
 var y = e.offsetY;
 // 鼠标按下移动时调用mousemove
 document.onmousemove = e => {
 // 元素ele移动的距离l
 var l = e.clientX - x;
 // 元素ele移动的距离l
 var t = e.clientY - y;
 this.ele.style.left = l + "px";
 this.ele.style.top = t + "px";
 }
 // 当鼠标弹起时,清空onmousemove与onmouseup
 document.onmouseup = () => {
 document.onmousemove = null;
 document.onmouseup = null;
 }
 }
 }
 // new一个MoveClass对象
 var moveClass = new MoveClass("#box");

效果如下,简单的拖拽

第二步—简单的缩放功能

1.设置方位

// ele的左,左上,左下,右,右上,右下,上,下
 MoveClass.prototype.editoptions = {
 left_top: true,
 left: true,
 right: true,
 top: true,
 bottom: true,
 right_top: true,
 left_bottom: true,
 right_bottom: true,
 }

2.给原型绑定缩放的方法

// 给原型绑定缩放的方法
 MoveClass.prototype.editEle = function () {
 // console.log(this.ele.clientWidth,this.ele.clientHeight);
 // console.log(this.ele.offsetLeft,this.ele.offsetTop);
 var that = this;
 // 创建一个div
 var div = document.createElement("div");
 // 遍历this.editoptions
 for (let attr in this.editoptions) {
 if (this.editoptions[attr]) {
 // 循环创建左,左上,左下,右,右上,右下,上,下方位的小点
 var dian = document.createElement("div");
 dian.className = "dian " + attr;
 // 设置类型为对应的attr
 dian.dataset.type = attr;
 // 当按下对应方位的小点时
 dian.onmousedown = e => {
 var e = e || window.event;
 // 先获取鼠标距离屏幕的left与top值
 var clientXY = {
 x: e.clientX,
 y: e.clientY
 }
 // 获取鼠标按下时ele的宽高
 var eleWH = {
 width: this.ele.clientWidth,
 height: this.ele.clientHeight,
 }
 // 阻止事件冒泡(针对父元素的move)
 e.stopPropagation();
 // 通过e.target获取精准事件源对应的type值
 var type = e.target.dataset.type;
 // 鼠标按下对应方位小点移动时,调用mousemove
 document.onmousemove = function (e) {
 // 查找type中是否包含”right“
 if (type.indexOf('right') > -1) {
 // console.log("right");
 // 如果拖拽后的宽度小于最小宽度,就return出去
 if (that.options.minWidth > eleWH.width + e.clientX - clientXY.x) {
 return;
 }
 // ele拖拽后的宽度为:初始width+拖拽后鼠标距离屏幕的距离 - 第一次按下时鼠标距离屏幕的距离
 that.ele.style.width = (eleWH.width + e.clientX - clientXY.x) + "px";
 }
 // 与”right“相同原理
 if (type.indexOf("bottom") > -1) {
 // console.log("bottom");
 if (that.options.minHeight > eleWH.height + e.clientY - clientXY.y) {
 return;
 }
 that.ele.style.height = (eleWH.height + e.clientY - clientXY.y) + "px"
 }

 if (type.indexOf("top") > -1) {
 // console.log("top");
 if (that.options.minHeight > eleWH.height - e.clientY + clientXY.y) {
 return;
 }
 // ele拖拽后的高度为:初始height-拖拽后鼠标距离屏幕的距离 + 第一次按下时鼠标距离屏幕的距离
 that.ele.style.height = (eleWH.height - e.clientY + clientXY.y) + "px";
 // 重新设置ele的top值为此时鼠标距离屏幕的y值
 that.ele.style.top = e.clientY + "px";
 }
 // 与”top“相同原理
 if (type.indexOf("left") > -1) {
 // console.log("left");
 if (that.options.minWidth > eleWH.width - e.clientX + clientXY.x) {
 return;
 }
 that.ele.style.width = (eleWH.width - e.clientX + clientXY.x) + "px";
 // 重新设置ele的left值为此时鼠标距离屏幕的x值
 that.ele.style.left = e.clientX + "px";
 }
 }
 document.onmouseup = function () {
 document.onmousemove = null;
 document.onmouseup = null;
 }
 }
 }
 // 将类名为”dian“的div添加到div中
 div.appendChild(dian);
 }
 // 为div设置类名
 div.className = "kuang"
 // 将类名为”kuang“的div添加到ele中
 this.ele.appendChild(div);
 }

效果图如下

最终效果,盒子可以拖动,可以缩放。

盒子上的8个小点采用定位放上去的,事先写好了样式

<style>
 * {
 margin: 0;
 padding: 0;
 }

 #box {
 width: 100px;
 height: 100px;
 background: orange;
 position: absolute;
 left: 100px;
 top: 100px;
 }

 .kuang {
 box-sizing: border-box;
 border: 1px solid #0f0;
 width: 100%;
 height: 100%;
 position: relative;
 }

 .kuang .dian {
 position: absolute;
 width: 10px;
 height: 10px;
 border-radius: 50%;
 background: #0f0;
 }

 .left_top {
 left: -5px;
 top: -5px;
 }

 .right_top {
 right: -5px;
 top: -5px;
 }

 .left_bottom {
 left: -5px;
 bottom: -5px;
 }

 .right_bottom {
 right: -5px;
 bottom: -5px;
 }

 .top {
 top: -5px;
 left: 50%;
 transform: translateX(-50%);
 }

 .bottom {
 bottom: -5px;
 left: 50%;
 transform: translateX(-50%);
 }

 .left {
 left: -5px;
 top: 50%;
 transform: translateY(-50%);
 }

 .right {
 right: -5px;
 top: 50%;
 transform: translateY(-50%);
 }
</style>
<body>
 <div id="box" class="border"></div>
</body>

所有的代码能直接粘贴使用。缩放的原理其实就是鼠标按下去时,获取当前的鼠标位置和盒子的宽高,鼠标按下并移动后获取此时的鼠标位置。

拖拽后的宽高=初始宽高+(拖拽后鼠标距离屏幕的位置 - 第一次按下时鼠标距离屏幕的位置)。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • js实现限定范围拖拽的示例

    限定范围拖拽 目录 代码实例 与简易拖拽的差异 下载源码链接 代码实例 * { padding: 0; margin: 0; } #box1 { width: 500px; height: 500px; background: #999; position: relative; left: 100px; top: 100px; } #box { width: 100px; height: 100px; background: #334; position: absolute; cursor: m

  • JS实现鼠标按下拖拽效果

    原生JS实现鼠标按下拖拽效果,供大家参考,具体内容如下 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv=&qu

  • JavaScript限制在客户区可见范围的拖拽(解决scrollLeft和scrollTop的问题)(2)

    限制范围的拖拽,要求被拖拽的对象必须在客户区可见范围! div是body的子元素,div的left/top是针对body的,不是针对可见客户区的,所以在拖拽的过程中不得不考虑被卷走的部分,因为网页文档可能很大,无论宽度还是高度都可能大于客户区,等于客户区大小就很好处理,大于的话就得考虑scrollTop和scrollLeft,否则div会跟鼠标脱离,因为距离都算错了. /*切记:凡是clientX/Y 的 一定记得卷走的部分*/ document.body是DOM中Document对象里的bod

  • javascript利用canvas实现鼠标拖拽功能

    利用canvas实现鼠标拖拽功能,当在元素上按下鼠标并移动时,元素跟着鼠标移动. 效果: 主要思路: 当鼠标按下时,用isPointInPath方法判断鼠标位置是否在元素上,如果在则鼠标移动时元素跟着移动:当鼠标抬起时,将鼠标移动事件和抬起事件置空. 代码如下: <canvas id="can" width="400" height="400"></canvas> <script type="text/ja

  • JS实现简单移动端鼠标拖拽

    本文实例为大家分享了JS实现移动端鼠标拖拽的具体代码,供大家参考,具体内容如下 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta ht

  • js实现拖拽与碰撞检测

    本文实例为大家分享了js实现拖拽与碰撞检测的具体代码,供大家参考,具体内容如下 拖拽 原理分析 对于拖拽一个div盒子,首先我们需要将鼠标移动到盒子上,然后按住鼠标左键,移动鼠标到目标位置,再松开鼠标,对于这一过程的分析, 显然需要三个鼠标事件: 按住鼠标:onmousedown 移动鼠标:onmousemove 松开鼠标:onmouseup 实现步骤 1.**鼠标按下时:**我们获取鼠标当前所在的位置距离页面左边界与上边界的距离,分别减去盒子距离页面左边界与上边界的值,这样我们 就得到了鼠标距

  • 移动端JS实现拖拽两种方法解析

    移动端的项目经常会引入手势库来实现拖拽 不过如果只是一两个页面用到拖拽,再引入一个手势库就很不划算 最近的项目中就有这么一个需求: 因为就这一个地方需要拖拽,所以我就没有引入第三方库 移动端的拖拽有两种主流的实现方案: 1. 将元素设置为固定定位,然后在拖拽的时候修改其定位,实现拖拽的效果: 2. 使用 transform 中的平移translate 属性实现拖拽. 方案一:固定定位 fixed 这种方案的核心就是给元素添加固定定位position:fixed; 但定位之后,元素会脱离文档流,会

  • 如何实现js拖拽效果及原理解析

    元素拖拽分成3个步骤:按下鼠标,移动鼠标,松开鼠标. 拖拽原理:按下拖拽元素后开始监听文档中鼠标移动事件,然后再监听鼠标松开事件:鼠标移动时,元素div要随着鼠标一起移动,需要计算元素div位移的距离(移动的距离=鼠标离可视窗口的位置 – 鼠标在div中相对于左上角的位置).然后松开鼠标时,删除移动事件和松开事件,元素完成拖拽. 一开始先监听鼠标按下事件mousedown,事件触发执行mouseHandler函数: div.addEventListener("mousedown",mo

  • JavaScript限定范围拖拽及自定义滚动条应用(3)

    两个对象:div1 和 div2,其中div1是div2的父元素,div2只能在div1的范围内拖拽 图中,红点是鼠标的位置,两个绿色箭头相减的结果就是disX,最后oEvent.clientX - disX 就是绿色箭头的部分,这个长度就是判断是否"出格"的依据,也就是这个短的绿色箭头范围应该在0 ~ div2.offsetWidth - div1.offsetWidth之间! <!DOCTYPE html> <html> <head> <m

  • JavaScript鼠标拖拽事件详解

    本文实例为大家分享了js鼠标拖拽事件的详细实现代码,供大家参考,具体内容如下 图片如下: css代码 <style> *{ margin:0; padding:0; } #box{ width: 200px; height: 200px; background: url("./img/aio.png") no-repeat; background-size: cover; position: absolute;/*定位元素 父级元素window就是初始包含块*/ top:0

随机推荐