HTML元素拖拽功能实现的完整实例


Posted in Javascript onDecember 04, 2020

1  需要了解的知识点

 1.1  offset(偏移量)

定义:元素在屏幕上占用的所有的可见的空间。

元素可见的大小由其高度、宽度决定,包括所有内边距、滚动条和边框大小四个属性

HTML元素拖拽功能实现的完整实例

offsetHeight:元素正在垂直方向上占用的大小空间,单位为px,不包括margin值。只读属性。

offsetWidth:元素在水平方向上占用的大小空间,单位为px,不包括margin值。只读属性。

offsetLeft:元素的左外边框至包含元素的左内边框之间的距离,单位为px。只读属性。

offsetTop:元素的上外边框至包含元素的上内边框之间的像素距离,单位为px。只读属性。

offsetParent:是一个元素最近的并且是定位过(relative || absolute)的父元素,如果没有父元素或者是父元素中没有一个是定位过的,返回值就是body元素。只读属性。

element.offsetLeft和element.offsetTop取值问题,分多种情况:

如果element是body的直接子元素,返回值则是element距离body左侧或顶部的距离;

如果element不是body的直接子元素,在父元素进行定位(relative或absolute)的情况下,各浏览器返回值都是element距离父元素左侧或者是顶部的距离(唯一的区别就是chrome没有把边框计算进去,IE、firefox都计算进去了);

如果element不是body的直接子元素,父元素也没有进行定位的情况下,各浏览器返回的直接是element元素距body的距离。

从上面可以看出offsetLeft、offsetTop返回的值就是element到offsetParent的距离,这个offsetParent是什么元素要看ele的父元素有没有进行定位(relative、absolute)。

1.2  client(客户区)

定义:元素的客户区大小(client dimension)指的是元素内容及其内边距所占距的空间大小。

HTML元素拖拽功能实现的完整实例

clientWidth:元素内容区宽度 + 左右内边距宽度,单位为px。内联元素以及没有 CSS 样式的元素的clientWidth属性值为 0。该属性包括内边距,但不包括垂直滚动条(如果有)、边框和外边距。只读属性。

clientHeight:元素内容区高度 + 上下内边距高度,单位为px。内联元素以及没有 CSS 样式的元素的clientHight属性值为 0。该属性包括内边距,但不包括水平滚动条(如果有)、边框和外边距。只读属性。

clientLeft:表示一个元素的左边框的宽度,单位为px。如果元素在左侧(右侧滚动条不算)有垂直滚动条,则该属性包括滚动条的宽度。clientLeft不包括左外边距和左内边距。只读属性。

clientTop:表示一个元素的上边框的宽度,单位为px。如果元素在顶部(底部滚动条不算)有水平滚动条,则该属性包括滚动条的宽度。clientTop不包括上外边距和上内边距。只读属性。

1.3  scroll(滚动区域)

我们一般看到的默认滚动条的宽度是17px。

滚动大小:指的是包含滚动内容的元素的大小。

HTML元素拖拽功能实现的完整实例

scrollHeight: 在没有滚动条的情况下,元素内容的总高度,单位为px。该尺寸包括元素的padding,但不包括元素的border、margin和水平滚动条宽度(如果存在)。

scrollWidth:在没有滚动条的情况下,元素内容的总宽度,单位为px。该尺寸包括元素的padding,但不包括元素的border、margin和垂直滚动条的宽度(如果存在)。

scrollLeft:被隐藏在内容区域左侧的像素值,通俗的解释就是元素水平滚动条到元素左边的距离。通过设置这个属性值可以改变元素的滚动位置。

scrollTop:被隐藏在内容区域上方的像素值,通俗的解释就是元素垂直滚动条到元素上方的距离。通过设置这个属性值可以改变元素的滚动位置。

1.4  window(窗口)

window.innerHeight:返回窗口的文档显示区的高度。

window.innerWidth:返回窗口的文档显示区的宽度。

window.outerWidth和window.outerHeight属性获取加上工具条与滚动条窗口的宽度与高度。

在Safari和Firefox中,outerWidth和outerHeight返回浏览器窗口本身的尺寸(无论是从最外层的window对象还是从某个框架访问)。在Opera中,这两个属性的值表示页面视图容器的大小。而innerWidth和innerHeight则表示该容器中页面视图区的大小(减去边框宽度)。在Chrome中,outerWidth.outerHeight与innerWidth,innerHeight返回相同的值,即视口(viewport)大小而非浏览器窗口大小。
IE没有提供取得当前浏览器窗口尺寸的属性。不过,它通过DOM提供了页面可见区域的相关信息。
在IE以及Firefox、Safari、Opera和Chrome中,document.documentElement.clientWidth和
document.documentElement.clientHeight中保存了页面视口的信息。在IE6中,这些属性必须在标准模式下才有效。如果是混杂模式,就必须通过docrunent.body.clientWidth和document.body.clientHeight取得相同信息。而对于混杂模式下的Chrome,则无论通过docurnent.documentElement还是document.body中的clientWidth和clientHeight属性,都可以取得视口的大小。

1.5  鼠标事件对象(mouseEvent)的一些属性

mEvent.clientX:返回鼠标触点相对于浏览器可见视区(或有效区域)左边沿的的X坐标,不包括任何滚动偏移,单位为px。这个值会根据用户对可见视区的缩放行为而发生变化。

mEvent.clientY:返回鼠标触点相对于浏览器可见视区(或有效区域)上边沿的的Y坐标,不包括任何滚动偏移,单位为px。这个值会根据用户对可见视区的缩放行为而发生变化。

mEvent.pageX:鼠标触点相对于HTML文档左边沿的的X坐标,单位为px。和clientX 属性不同,这个值是相对于整个html文档的坐标,和用户滚动位置无关。因此当存在水平滚动的偏移时,这个值包含了水平滚动的偏移。

mEvent.pageY:鼠标触点相对于HTML文档上边沿的的Y坐标,单位为px。和clientY 属性不同,这个值是相对于整个html文档的坐标,和用户滚动位置无关。因此当存在垂直滚动的偏移时,这个值包含了垂直滚动的偏移。

mEvent.screenX:返回鼠标触点相对于屏幕左边沿的X坐标,单位为px。不包含页面滚动的偏移量。

mEvent.screenY:返回鼠标触点相对于屏幕上边沿的Y坐标,单位为px。不包含页面滚动的偏移量。

mEvent.offsetX:当鼠标事件发生时,鼠标触点距离事件源元素左侧的X轴方向上的距离,单位为px。

mEvent.offsetY:当鼠标事件发生时,鼠标触点距离事件源元素顶部的Y轴方向上的距离,单位为px。

2  示例演示

 2.1  元素水平拖拽效果实现

<!DOCTYPE html>
<html lang="en">
<head>
 <meta charset="UTF-8">
 <meta name="viewport" content="width=device-width, initial-scale=1.0">
 <meta http-equiv="X-UA-Compatible" content="ie=edge">
 <title>Document</title>
</head>
<body>
 <div id="blackSquare" style="position: absolute; width:50px; height:50px; background-color: black;cursor: pointer;"></div>
</body>
<script>
 window.onload = () => {
 //获取拖拽实验对象
 let el=document.getElementById("blackSquare");
 //在该对象上绑定鼠标点击事件
 el.onmousedown = (e) => {
 //鼠标按下,计算鼠标触点距离元素左侧的距离
 let disX = e.clientX - el.offsetLeft;
 document.onmousemove = function (e) {
 //计算需要移动的距离
 let t = e.clientX - disX;
 //移动当前元素
 if (t >= 0 && t <= window.innerWidth - el.offsetWidth) {
 el.style.left = t + 'px';
 } 
 };
 //鼠标松开时,注销鼠标事件,停止元素拖拽。
 document.onmouseup = function (e) {
 document.onmousemove = null;
 document.onmouseup = null;
 };
 } 
 }
</script>
</html>

HTML元素拖拽功能实现的完整实例

2.2  元素垂直拖拽效果实现

<!DOCTYPE html>
<html lang="en">
<head>
 <meta charset="UTF-8">
 <meta name="viewport" content="width=device-width, initial-scale=1.0">
 <meta http-equiv="X-UA-Compatible" content="ie=edge">
 <title>Document</title>
</head>
<body>
 <div id="blackSquare" style="position: absolute; width:50px; height:50px; background-color: black;cursor: pointer;"></div>
</body>
<script>
 window.onload = () => {
 //获取拖拽实验对象
 let el=document.getElementById("blackSquare");
 //在该对象上绑定鼠标点击事件
 el.onmousedown = (e) => {
 //鼠标按下,计算鼠标触点距离元素左侧的距离
 let disY = e.clientY - el.offsetTop;
 document.onmousemove = function (e) {
 //计算需要移动的距离
 let t = e.clientY - disY;
 //移动当前元素
 if (t >= 0 && t <= window.innerHeight - el.offsetHeight) {
 el.style.top = t + 'px';
 } 
 };
 //鼠标松开时,注销鼠标事件,停止元素拖拽。
 document.onmouseup = function (e) {
 document.onmousemove = null;
 document.onmouseup = null;
 };
 } 
 }
</script>
</html>

HTML元素拖拽功能实现的完整实例

2.3  元素任意方向拖拽效果实现

<!DOCTYPE html>
<html lang="en">
<head>
 <meta charset="UTF-8">
 <meta name="viewport" content="width=device-width, initial-scale=1.0">
 <meta http-equiv="X-UA-Compatible" content="ie=edge">
 <title>Document</title>
</head>
<body>
 <div id="blackSquare" style="position: absolute; width:50px; height:50px; background-color: black;cursor: pointer;"></div>
</body>
<script>
 window.onload = () => {
 //获取拖拽实验对象
 let el=document.getElementById("blackSquare");
 //在该对象上绑定鼠标点击事件
 el.onmousedown = (e) => {
 //鼠标按下,计算鼠标触点距离元素左侧和顶部的距离
 let disX = e.clientX - el.offsetLeft;
 let disY = e.clientY - el.offsetTop;
 document.onmousemove = function (e) {
 //计算需要移动的距离
 let tX = e.clientX - disX;
 let tY = e.clientY - disY;
 //移动当前元素
 if (tX >= 0 && tX <= window.innerWidth - el.offsetWidth) {
 el.style.left = tX + 'px';
 } 
 if (tY >= 0 && tY <= window.innerHeight - el.offsetHeight) {
 el.style.top = tY + 'px';
 } 
 };
 //鼠标松开时,注销鼠标事件,停止元素拖拽。
 document.onmouseup = function (e) {
 document.onmousemove = null;
 document.onmouseup = null;
 };
 } 
 }
</script>
</html>

HTML元素拖拽功能实现的完整实例

3  参考文献

https://developer.mozilla.org/zh-CN/docs/Web/API/Element

https://developer.mozilla.org/zh-CN/docs/Web/API/Touch

https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent

到此这篇关于HTML元素拖拽功能实现的文章就介绍到这了,更多相关HTML元素拖拽功能内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Javascript 相关文章推荐
javascript实现unicode和字符的互相转换
Jul 18 Javascript
JavaScript EasyPager 分页函数
May 25 Javascript
jQuery向上遍历DOM树之parents(),parent(),closest()之间的区别
Dec 02 Javascript
$(document).ready(function() {})不执行初始化脚本
Jun 19 Javascript
js实现获取当前时间是本月第几周的方法
Aug 11 Javascript
jQuery带进度条全屏图片轮播特效代码分享
Jun 28 Javascript
使用JQuery实现Ctrl+Enter提交表单的方法
Oct 22 Javascript
jQuery对象与DOM对象转换方法详解
May 10 Javascript
Vue2.0实现购物车功能
Jun 05 Javascript
angular学习之动态创建表单的方法
Dec 07 Javascript
微信小程序配置服务器提示验证token失败的解决方法
Apr 03 Javascript
JS操作Fckeditor的一些常用方法(获取、插入等)
Feb 19 Javascript
解决Vue-cli3没有vue.config.js文件夹及配置vue项目域名的问题
Dec 04 #Vue.js
vue基于Echarts的拖拽数据可视化功能实现
Dec 04 #Vue.js
addEventListener()和removeEventListener()追加事件和删除追加事件
Dec 04 #Javascript
vue使用echarts图表自适应的几种解决方案
Dec 04 #Vue.js
原生JS实现拖拽效果
Dec 04 #Javascript
vue-calendar-component 封装多日期选择组件的实例代码
Dec 04 #Vue.js
如何正确解决VuePress本地访问出现资源报错404的问题
Dec 03 #Vue.js
You might like
如何在PHP中进行身份认证
2006/10/09 PHP
PHP5中的this,self和parent关键字详解教程
2007/03/19 PHP
记录mysql性能查询过程的使用方法
2013/05/02 PHP
详解PHP中的状态模式编程
2015/08/11 PHP
javascript中的关于类型转换的性能优化
2010/12/14 Javascript
JavaScript传递变量: 值传递?引用传递?
2011/02/22 Javascript
.net,js捕捉文本框回车键事件的小例子(兼容多浏览器)
2013/03/11 Javascript
JS实现Fisheye效果动感放大菜单代码
2015/10/21 Javascript
一个简单不报错的summernote 图片上传案例
2016/07/11 Javascript
使用JavaScript触发过渡效果的方法
2017/01/19 Javascript
javascript浏览器用户代理检测脚本实现方法
2017/10/27 Javascript
jQuery实现的五星点评功能【案例】
2019/02/18 jQuery
JavaScript表格隔行变色和Tab标签页特效示例【附jQuery版】
2019/07/11 jQuery
微信小程序常用的3种提示弹窗实现详解
2019/09/19 Javascript
微信小程序实现点击按钮后修改颜色
2019/12/05 Javascript
jQuery实现中奖播报功能(让文本滚动起来) 简单设置数值即可
2020/03/20 jQuery
vue-cli —— 如何局部修改Element样式
2020/10/22 Javascript
python面向对象_详谈类的继承与方法的重载
2017/06/07 Python
python matplotlib中文显示参数设置解析
2017/12/15 Python
Python中staticmethod和classmethod的作用与区别
2018/10/11 Python
完美解决Python matplotlib绘图时汉字显示不正常的问题
2019/01/29 Python
python使用Matplotlib改变坐标轴的默认位置
2019/10/18 Python
Python CategoricalDtype自定义排序实现原理解析
2020/09/11 Python
高品质和独特的产品世界:Creations and Collections
2018/01/07 全球购物
美味咖啡的顶级烘焙师:Cafe Britt
2018/03/15 全球购物
电气自动化大学生求职信
2013/10/16 职场文书
年终晚会主持词
2014/03/25 职场文书
安全生产责任书范本
2014/04/15 职场文书
十佳中学生事迹材料
2014/06/02 职场文书
考研复习计划
2015/01/19 职场文书
Django项目如何正确配置日志(logging)
2021/04/29 Python
Python爬虫实战之爬取携程评论
2021/06/02 Python
浅谈@Value和@Bean的执行顺序问题
2021/06/16 Java/Android
教你利用Nginx 服务搭建子域环境提升二维地图加载性能的步骤
2021/09/25 Servers
python套接字socket通信
2022/04/01 Python
Vue OpenLayer测距功能的实现
2022/04/20 Vue.js