原生拖拽模型(有限制范围的)

思路:

确定盒子的移动的方式

​ 1、 定位的left top值可以让盒子移动

​ 2、直接margin 顶(在文档流中,不建议) 父元素的padding顶 (更加不建议)

​ 使用left来实现 ,需要设置定位。全部用 相对定位(叠加计算) 绝对定位都能实现(相对是谁,如果代码多,会很乱。),

这里我们使用 父相子绝(边界相对定位,移动的盒子绝对定位)

确定是否有边界

​ 移动的盒子不能超过设置的边界。

​ 判断边界有很多方法。可以使用移动盒子的四个角到视口的距离判断,也可以使用盒子能够移动的left来进行判断边界。

​ 这里我们使用 可以移动的最大值来判断。

横向可以移动的最大 就是边界宽 - 移动盒子的宽
纵向可以移动的最大top 就是边界的高 - 移动盒子的高

思考都触发了什么事件。

​ 盒子被拖动,首先需要 盒子被鼠标 按下不抬起(onmousedown), 然后是拖动(onmousemove),鼠标松开(onmouseup)

深度思考。 确保鼠标在触发鼠标按下不抬起的点,移动到终点的时候,点还在盒子的上相同位置。这个盒子该怎么样绘制。

我们这里使用的思路就是

盒子移动,需要知道鼠标 “点”在哪里 ,然后根据移动后的“点”再绘制盒子,这里通过为盒子设置的left和top值,让盒子移动,移动的left和top减去点在盒子上的距离。就可以保证点还在盒子的相同位置上。

​ 我们可以盒子的四个角来做运算,我们这里选择使用 左上角来计算 left值和top值。

这个时候我们又有了两种算法,left 可以相对于 父元素的边框,也可以根据上次移动的left 进行叠加。其实,这都是相对于父元素的边框。(注意,我们的盒子现在是绝对定位。)来一张丑陋的图。我们不用叠加。用简单,不走坑的,相对于大盒子的left。

​ 那么此时, 需要小盒子左边框的值到黑盒子,我们可以通过 左上角的点来算。

​ 点在哪里 使用只读属性 offsetX 和offsetY 得到鼠标的点在小盒子中的位置

​ 小黑盒子 : 点到视口的位置 clientX clientY 减去 点在小绿盒子的offsetX 和 offsetY

​ 再减去 大盒子 到视口的位置(pageX),大盒子到视口的位置可以选择使用 getComputedStyle(IE也不支持,我用的IE全指的是IE8,IE用的解析是currentStyle。可以做这么一个兼容) 浏览器解析之后的样式计算,也可以使用pageX,pageY 求得

​ 这里我们使用pageX和 pageY 来做图。(page是事件对象,并且IE不支持。下一遍原生js封装page函数,就可以调用page函数来实现,代码我们暂时先用getComputedStyle。想要兼容的小伙伴可以解析样式这里做一个兼容)。

​ 然后进去大盒子的边框。(这里我们使用clientLeft得到左边框)。然后就可以得到的 left 移动值, 相对于大黑盒子移动left。就可以达到相同的位置(展示)

​ 所以移动的left值就为

left值 = 移动后“点”的视口的x坐标 - 元素的偏移x坐标(offsetX) - 父元素到页面的距离(pageX) - 父元素的边框(clientLeft)。

1、 需要的事件 onmousedown、onmousemove、onmouseup

2、使用定位的left和top 来作为盒子移动。

3、边界的判断使用 可以移动的最大值

* {margin: 0;padding: 0;
}
#box {width: 500px;height: 500px;border: 1px solid red;margin: 0 auto;position: relative;
}
#move {width: 100px;height: 100px;background-color: orange;position: absolute;left: 0;top: 0;
}
<div id="box"><div id="move"></div>
</div>
var box = document.getElementById('box');
var move = document.getElementById('move');// 最大可以移动距离
var maxLeft = parseFloat(getComputedStyle(box).width) - parseFloat(getComputedStyle(move).width);
var maxTop = parseFloat(getComputedStyle(box).height) - parseFloat(getComputedStyle(move).height);// 获得盒子到 距离 视口 的宽和高
var leftt = getComputedStyle(box).marginLeft;   // 得到的是px
var topp = getComputedStyle(box).top;move.onmousedown = function(e) {// 兼容evar e = e || event; // console.log('dd');// 获得点击位置的  元素偏移量  x yvar ox = e.offsetX;var oy = e.offsetY;//  console.log(leftt);document.onmousemove = function(e) {var e = e || event; //   点击 点 视口的 x yvar cx = e.clientX;var cy = e.clientY;console.log(leftt);// 获得移动了的 left  和 height   再减外边盒子的边框var left = cx - ox - parseFloat(leftt);var top = cy - oy - parseFloat(topp);//  console.log(left);// console.log(cx- ox);// 因为有边界 ,所以  判断边界值/* 判断边界的方法   1.   四个角的点   判断边界  2.   可移动的长度进行  判断  *//* 用可移动的长度进行判断 */left = left < 0? 0: left;left = left > maxLeft? maxLeft: left;top = top < 0? 0: top;top = top > maxTop? maxTop: top;// console.log(max);//  css开始变move.style.left = left + 'px';move.style.top = top + 'px';}
}// 鼠标抬起
document.onmouseup = function() {document.onmousemove = null;
}

原生JS拖拽模型(有限制范围的)相关推荐

  1. React.js实现原生js拖拽效果及思考

    一.起因&思路 不知不觉,已经好几天没写博客了...近来除了研究React,还做了公司官网... 一直想写一个原生js拖拽效果,又加上近来学react学得比较嗨.所以就用react来实现这个拖 ...

  2. vuejs 原生JS 拖拽事件案例

    原生JS or Vue 事件案例合集(详细) 提示:这里可以添加系列文章的所有文章的目录,目录需要自己手动添加 Section 1 单个或多个鼠标拖拽事件的理解 提示:写完文章后,目录可以自动生成,如 ...

  3. go语言接收html上传的文件,html5原生js拖拽上传(golang版)

    package main import ("fmt" "io" "net/http" "os")const( uploa ...

  4. html中给li赋值,原生js拖拽ul里面的li给input赋值

    css部分 * { margin: 0; padding: 0; } .wallpaper { width: 800px; margin: 50px auto; } .dragTextBox { po ...

  5. 【加强版】js原生实现拖拽效果,这次没有用document的mousedown、mousemove、mouseup事件我们来点实际的(但是有个弊端:拖拽过程中鼠标会变成一个禁用符号,不太友好)

    <div class='dragged'></div> //初始化需要拖拽的列initDrags() {var arr = document.querySelectorAll( ...

  6. 【墙裂推荐】【原生基础版】js原生实现拖拽效果,注意不要忘了div的cursor用grab和grabbing 还是古法炮制、传统工艺的原生代码兼容性最好,推荐

    以下方式的劣势就是在放弃拖拽那一刻会触发click事件,通常如果被拖拽元素还有其他点击事件,会重复触发,往往并非业务需求.优势就是-额-貌似这段代码没什么屌优势! <div class='dra ...

  7. sortable 拖拽时互换目标的位置_双端通用型JS拖拽插件的封装与应用

    最近工作中遇到一个需求,需要将一个元素从某位置拖动到另一固定位置后执行某一交互行为,具体效果如下: 这个看似简单的需求,然而实现起来却并不那么顺利.我首先想到的是如何通过哪个现有的插件来快速解决这个问 ...

  8. html列表拖拽排序插件,JS拖拽排序插件Sortable.js用法实例分析

    本文实例讲述了JS拖拽排序插件Sortable.js用法.分享给大家供大家参考,具体如下: 最近由于项目功能设计的原因,需要对table中的行实现拖拽排序功能,找来找去发现Sortable.js能很好 ...

  9. js拖拽360桌面悬浮球代码

    js拖拽360桌面悬浮球代码 原生js制作简单好用的360桌面悬浮球,可拖拽到浏览器边缘,自动贴边,自动适应屏幕效果. 演示地址 下载地址

最新文章

  1. getcoo php_PHP简单实现DES加密解密的方法
  2. BZOJ 1612: [Usaco2008 Jan]Cow Contest奶牛的比赛【Floyd】
  3. 使用Tensorflow构建和训练自己的CNN来做简单的验证码识别
  4. js中当等于最小值是让代码不执行_网页中JS函数自动执行常用三种方法
  5. Python 在字符串中处理html 和xml
  6. linux 没有root登陆
  7. 无法从传输连接中读取数据:远程主机强迫_电力远程抄表中的应用
  8. jqgrid下treegrid排序问题
  9. Java cache类型_为什么有些Java 类方法中要cache类变量
  10. JarvisOJ Basic 熟悉的声音
  11. TextView属性的静态使用与动态使用
  12. 存数据返回他的序列号id_雪花般的分布式唯一ID雪花算法
  13. idea 包.路径切换为目录结构
  14. 毕业论文格式大全、排版技巧及常见问题汇总
  15. Ubuntu 安装显卡驱动 CUDA10 cuDNN详细教程
  16. 【Flutter--实战】Dart 语言快速入门
  17. 【Ant Design Vue】封装导出Excel文件的功能模块到ele-pro-table
  18. 关于SEL的一些总结
  19. nw.js html5,用nw.js构建项目
  20. 基于element-ui 搭建管理后台

热门文章

  1. MacOS下Go语言环境搭建
  2. Bootstrap排版之标题
  3. 笔记本触摸板基本代替鼠标的常用操作
  4. 前端css解决z-index 上层元素遮挡下层元素的方法
  5. 在网页中内嵌视频,例如优酷
  6. 腾讯视频和优酷视频怎么嵌入网页的方法
  7. bi java lajp 和php_新宠混血儿诞生记--Java+PHP整合
  8. Web前端是什么?Web前端包括哪些技术?
  9. Oracle查询表空间
  10. mysql数据库结构导出word_Windows导出MySQL数据库表结构到Word文档-DBExportDoc V1.0 For MySQL...