第一步

  首先简单分析下需求吧,我们就是想实现鼠标拖拽带颜色的方块时,让方块停留在鼠标松开的位置,需要计算的就是拖拽前的坐标和拖拽后的坐标,鼠标移动后相对于原位置的偏移量=目标元素的偏移量,根据这个等式和几个属性实现拖拽(下面会介绍到这几个属性,莫急哈,后面还会遇到一个小问题,一会详细描述),鼠标的状态事件有三种,鼠标按下时的事件(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拖拽原理及简单实现(渣渣自学)的更多相关文章

  1. js拖拽原理和碰撞原理

    拖拽的原理onmousedown 选择元素onmousemove 移动元素onmouseup 释放元素 1:如果拖拽的时候有文字:被选中,会产生问题原因:当鼠标按下的时如果页面中有文字或者图片被选中的 ...

  2. javascript拖拽原理与简单实现方法[demo]

    美国人有一句常用的俗语—“Re-inventing the Wheel”,从字面上来解释就是“重新发明轮子”.可是轮子早已问世,再要去发明岂非劳而无功? 产品经理发下需求,实施者再到网上搜索代码,也许 ...

  3. JS拖拽原理

    实现拖拽效果主要跟鼠标的三个事件有关: onmousedown : 选择要拖拽的元素 onmousemove : 移动元素 onmouseup : 释放元素 三个事件的关系: obj.onmoused ...

  4. js拖拽效果的实现及原理

    元素拖拽分成3个步骤:按下鼠标,移动鼠标,松开鼠标. 拖拽原理:按下拖拽元素后开始监听文档中鼠标移动事件,然后再监听鼠标松开事件:鼠标移动时,元素div要随着鼠标一起移动,需要计算元素div位移的距离 ...

  5. 一步一步实现JS拖拽插件

    js拖拽是常见的网页效果,本文将从零开始实现一个简单的js插件. 一.js拖拽插件的原理 常见的拖拽操作是什么样的呢?整过过程大概有下面几个步骤: 1.用鼠标点击被拖拽的元素 2.按住鼠标不放,移动鼠 ...

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

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

  7. 关于 JS 拖拽功能的冲突问题及解决方法

    前言 我在之前写过关于 JS 拖拽的文章,实现方式和网上能搜到的方法大致相同,别无二致,但是在一次偶然的测试中发现,这种绑定事件的方式可能会和其它的拖拽事件产生冲突,由此产生了对于事件绑定的思考.本文 ...

  8. 浅谈js拖拽

    本文来自网易云社区 作者:刘凌阳 前言 本文依据半年前本人的分享<浅谈js拖拽>撰写,算是一篇迟到的文章. 基本思路 虽然现在关于拖拽的组件库到处都是,HTML5也把拖放纳入了标准.但考虑 ...

  9. 再谈React.js实现原生js拖拽效果

    前几天写的那个拖拽,自己留下的疑问...这次在热心博友的提示下又修正了一些小小的bug,也加了拖拽的边缘检测部分...就再聊聊拖拽吧 一.不要直接操作dom元素 react中使用了虚拟dom的概念,目 ...

随机推荐

  1. 我能想到的最浪漫的Java网络教程之Socket,三步到位!!!

    简说 如果要使用Java中的TCP/IP通过网络连接到服务器,则需要创建一个java.net.Socket对象以连接到服务器.如果使用JavaNIO,则还可以在JavaNIO中创建SocketChan ...

  2. asp.netcore 3.1 program、Startup 类详解

    Program类 public class Program { /// <summary> /// 应用程序入口 /// 1.asp.netcore 本质上是控制台程序 /// </ ...

  3. Revit二次开发——非模态窗口的事件处理

    一.起因    自己在写revit二开时,有一个Winform窗体按钮点击事件需要 触发调用事务进行处理,结果出现“异常“Starting a transaction from an external ...

  4. 群晖系统设置链路聚合并配置静态IP的教程【江东网 JDX86.COM】

    1.进入控制面板 > 网络 > 网络接口.请单击创建 > 创建 Bond 2.进入聚合配置向导,选择你想要的模式,这里有几种模式意思分别为: 自适应负载平衡: 此模式优化了 Syno ...

  5. IP-master

    http://www.igotaobao.cn/IP-master/

  6. Spring @Transactional事物配置无效原因

    spring @transaction不起作用,Spring事物注意事项 1. 在需要事务管理的地方加@Transactional 注解.@Transactional 注解可以被应用于接口定义和接口方 ...

  7. kvm 虚拟机中鼠标不同步的问题解决方法

    在<devices>标签下添加 <input type='tablet' bus='usb'/>    

  8. IE浏览器连接WebSocket报错:java.lang.IllegalArgumentException: Invalid character found in the request target. The valid characters are defined in RFC 7230 and RFC 3986

    在项目开发中整合了WebSocket,本来没什么问题了,但是偶尔发现用IE浏览器打开web端不能推送消息,因为PC端与服务器建立连接失败了.网上查了很多资料, 又看了看源码,都不对症:又怀疑是Spri ...

  9. Vue 构造选项 - 进阶

    Directive指令:减少DOM操作的重复 Vue实例/组件用于数据绑定.事件监听.DOM更新 Vue指令主要目的就是原生DOM操作 减少重复 自定义指令 两种声明方式 方法一:声明一个全局指令 V ...

  10. codeforce Round #599(Div.2)

    题目传送门 A. Maximum Square 题目意思是给你n个长条,每个长条的高度是num[i](0 < i < n),每一条的宽度都是 1 :然后求这些长条可以组成的最大面积的正方形 ...