js拖拽原理及简单实现(渣渣自学)
第一步
首先简单分析下需求吧,我们就是想实现鼠标拖拽带颜色的方块时,让方块停留在鼠标松开的位置,需要计算的就是拖拽前的坐标和拖拽后的坐标,鼠标移动后相对于原位置的偏移量=目标元素的偏移量,根据这个等式和几个属性实现拖拽(下面会介绍到这几个属性,莫急哈,后面还会遇到一个小问题,一会详细描述),鼠标的状态事件有三种,鼠标按下时的事件(mousedown),鼠标移动时的事件(mousemove),鼠标松开时的事件(mouseup)
第二部
这里就是撸代码了,首先新建一个html页面
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<style>
#div{
position: absolute;
width:100px;
height: 100px;
background-color: deeppink;
}
</style>
<body style="border:1px solid #000;height: 600px;margin:0">
<div id="div"></div>
<script>
let tar=document.getElementById('div')
let isDrag=false;
tar.onmousedown=function(el){
var el= el || event;
isDrag=true
if(isDrag){
document.onmousemove=function(e){
var e = e || event;
tar.style.left= e.clientX - el.offsetX + 'px';
tar.style.top= e.clientY - el.offsetY + 'px';
}
} else {
return
}
document.onmouseup=function(){
isDrag=false;
// tar.onmousedown=null;
document.onmousemove=null
document.onmouseup=null
}
} </script>
</body>
</html>
这里时完整的代码,我一步一步的来解释
(1)<body style="border:1px solid #000;height: 600px;margin:0">这段代码起了个初始化的作用,(因为谷歌浏览器会默认给body加8px的margin)border加不加无所谓,我加上是方便看一下边界;
(2)position: absolute; 样式中的这个东西不能缺,因为只用元素定位了之后才能使用top和left属性;
(3)页面中的isDrag就相当于一个开关,只有当为true的时候才允许拖拽(也就是鼠标按下的时候才能拖拽,松开时isDrag自动变为false,mousemove事件就不能触发了)
(4)var e = e || event(window.event); 这行代码其实也很好理解,就是为了兼容,它就相当于一个函数中运用三目给e重新赋值,
(function(event){
var e = event ? event : window.event
})()
这样理解就简单了,上面说了个小问题是啥,现在可以揭晓了,把页面中的var 换成let试一下,
浏览器控制台报了一行错,如下
Uncaught SyntaxError: Identifier 'el' has already been declared
(星星个b的),咋报错了,为啥啊,咋回事啊? 赶紧百度一下压压惊,
不废话了,简单解释下,这里涉及到两个知识点:函数的形参以及let和var声明变量的区别,函数的形参也是函数作用域的参数,也就是函数调用后形成的局部作用域内的参数,它不属于全局哦,也就相当于使用let声明了这个参数,有人会问了,用var咋就可以呢,咋就不报错呢,因为var声明的变量会覆盖掉同名变量(也就是覆盖了形参),不要杠为啥覆盖,js就是这么定义的,百度下答案都是大同小异,王八的屁股--龟腚(规定),
tar.style.left= e.clientX - el.offsetX + 'px';
tar.style.top= e.clientY - el.offsetY + 'px'; 这两行代码就是计算元素的left和top的代码,position天天用,top和left不难理解,e.clientX就是鼠标终点距离div左边的垂直距离,e.clientY就是距离div上边的垂直距离,
el.offsetX 是div距离浏览器左边的距离,el.offsetY 是距离浏览器页面显示区的距离,页面显示区的上边,标签栏下面,有一条灰边,鼠标动的时候这四个值也是在不断变化的,只要设置一下div的top和left就能实现简单的拖拽功能了
(5)mouseup事件是释放空间,节约内存。
这样就完成了一个简单的拖拽。后面再一起学习复杂拖拽(比方说,限制范围,拖拽生成新的等等)
document.onmouseup=null
js拖拽原理及简单实现(渣渣自学)的更多相关文章
- js拖拽原理和碰撞原理
拖拽的原理onmousedown 选择元素onmousemove 移动元素onmouseup 释放元素 1:如果拖拽的时候有文字:被选中,会产生问题原因:当鼠标按下的时如果页面中有文字或者图片被选中的 ...
- javascript拖拽原理与简单实现方法[demo]
美国人有一句常用的俗语—“Re-inventing the Wheel”,从字面上来解释就是“重新发明轮子”.可是轮子早已问世,再要去发明岂非劳而无功? 产品经理发下需求,实施者再到网上搜索代码,也许 ...
- JS拖拽原理
实现拖拽效果主要跟鼠标的三个事件有关: onmousedown : 选择要拖拽的元素 onmousemove : 移动元素 onmouseup : 释放元素 三个事件的关系: obj.onmoused ...
- js拖拽效果的实现及原理
元素拖拽分成3个步骤:按下鼠标,移动鼠标,松开鼠标. 拖拽原理:按下拖拽元素后开始监听文档中鼠标移动事件,然后再监听鼠标松开事件:鼠标移动时,元素div要随着鼠标一起移动,需要计算元素div位移的距离 ...
- 一步一步实现JS拖拽插件
js拖拽是常见的网页效果,本文将从零开始实现一个简单的js插件. 一.js拖拽插件的原理 常见的拖拽操作是什么样的呢?整过过程大概有下面几个步骤: 1.用鼠标点击被拖拽的元素 2.按住鼠标不放,移动鼠 ...
- React.js实现原生js拖拽效果及思考
一.起因&思路 不知不觉,已经好几天没写博客了...近来除了研究React,还做了公司官网... 一直想写一个原生js拖拽效果,又加上近来学react学得比较嗨.所以就用react来实现这个拖 ...
- 关于 JS 拖拽功能的冲突问题及解决方法
前言 我在之前写过关于 JS 拖拽的文章,实现方式和网上能搜到的方法大致相同,别无二致,但是在一次偶然的测试中发现,这种绑定事件的方式可能会和其它的拖拽事件产生冲突,由此产生了对于事件绑定的思考.本文 ...
- 浅谈js拖拽
本文来自网易云社区 作者:刘凌阳 前言 本文依据半年前本人的分享<浅谈js拖拽>撰写,算是一篇迟到的文章. 基本思路 虽然现在关于拖拽的组件库到处都是,HTML5也把拖放纳入了标准.但考虑 ...
- 再谈React.js实现原生js拖拽效果
前几天写的那个拖拽,自己留下的疑问...这次在热心博友的提示下又修正了一些小小的bug,也加了拖拽的边缘检测部分...就再聊聊拖拽吧 一.不要直接操作dom元素 react中使用了虚拟dom的概念,目 ...
随机推荐
- 极简 Node.js 入门 - 2.1 Path
极简 Node.js 入门系列教程:https://www.yuque.com/sunluyong/node 本文更佳阅读体验:https://www.yuque.com/sunluyong/node ...
- K8s集群verification error" while trying to verify candidate authority certificate "kubernetes"
问题内容 because of "crypto/rsa: verification error" while trying to verify candidate authorit ...
- Homekit_Dohome_月球灯
此款月球灯可以使用Homekit或者Dohome App进行有效的智能控制,支持多种色彩和亮度调节,功能强大,有兴趣的可以去以下链接看看: https://item.taobao.com/item.h ...
- DAPP开发初探——永存的留言
转载地址 https://blog.csdn.net/qq_33764491/article/details/80570266 前言 最近DAPP的开发貌似很火,学习了区块链的一些知识之后,相信有很多 ...
- DRF内置认证组件之自定义认证系统
自定义token认证 我们知道,在django项目中不管路由以及对应的视图类是如何写的,都会走到 dispatch 方法,进行路由分发, 在阅读 APIView类中的dispatch 方法的源码中,有 ...
- Linked server的一个问题
好久没有写新的博客,主要是很久没有什么动力和需求来写程序.虽然也不是一点没写,但都缺乏技术含量,没什么可说的. 前两天碰到一个关于linked server的问题.本地的sql server里,通过l ...
- 顶级技术盛会KubeCon 2020,网易轻舟布道多云环境云原生应用交付
在日前的KubeCon 2020中国线上峰会上,VMware中国研发中心架构师.Harbor项目创始人和维护者张海宁,和网易数帆轻舟事业部架构师.Harbor维护者裴明明,共同分享了如何在多云和多集群 ...
- Mybatis 循环删除/插入
<foreach collection="array" open="(" separator="," close=")&qu ...
- C# 中生成随机数
生成1-100之间的随机数: new Random().Next(1, 100) 但是输出的结果是一样的,因为Random调用无参的构造函数其实调用的是 有参的构造函数,传递的 默认值: Enviro ...
- Word操作之参考文献自动关联和引用
转载:https://blog.csdn.net/qq_40078121/article/details/88681605 编号选项->定义新编号格式: 选择插入->交叉引用选项: 然后选 ...