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的概念,目 ...
随机推荐
- Dubbo系列之 (二)Registry注册中心-注册(1)
引导 dubbo的服务的注册与发现,需要通过第三方注册中心来协助完成,目前dubbo支持的注册中心包括 zookeeper,consul,etcd3,eureka,nacas,redis,sofa.这 ...
- 《SOD框架企业级应用数据架构实战》新书简介和预定
SOD框架“企业级”应用数据架构实战 ----致敬平凡的程序员! 历时两年写成, 两大MVP: 张善友. 刘冰(宇内流云) JAVA技术专家 申毅 联合推荐! 10年磨一剑:汇聚作者超过10年的架构工 ...
- C#LeetCode刷题-并查集
并查集篇 # 题名 刷题 通过率 难度 128 最长连续序列 39.3% 困难 130 被围绕的区域 30.5% 中等 200 岛屿的个数 38.4% 中等 547 朋友圈 45.1% ...
- C#LeetCode刷题之#13-罗马数字转整数(Roman to Integer)
问题 该文章的最新版本已迁移至个人博客[比特飞],单击链接 https://www.byteflying.com/archives/3842 访问. 罗马数字包含以下七种字符: I, V, X, L, ...
- 01 树莓派4B—C语言编程——GPIO
#include <stdio.h>#include <wiringPi.h> int main( void){ int LED1 = 1; int LED4 = 4; wir ...
- JavaScript基础-03
1. 条件判断语句 若条件成立才会执行,条件不成立则语句不执行: if语句 语法一: if(条件表达式) {语句} :true就执行,false不执行: 语法二: if(条件表达式) ...
- 不用虚机不用Docker使用Azure应用服务部署ASP.NET Core程序
一般我们写好了应用程序想要部署发布它,要么发布到物理机,要么发布到虚拟机,要么发布到容器来运行它.现在有了Azure应用服务,我们可以完全不用管这些东西,只管写好自己的代码,然后使用VisualStu ...
- Python 读取word中表格数据、读取word修改并保存、替换word中词汇、读取word中每段内容,读取一段话中相同样式内容,理解Document中run
from docx import Document path = r'D:\pywork\12' # word信息表所在文件夹 w = Document(path + '/' + 'word信息表.d ...
- 实践案例丨教你一键构建部署发布前端和Node.js服务
如何使用华为云服务一键构建部署发布前端和Node.js服务 构建部署,一直是一个很繁琐的过程 作为开发,最害怕遇到版本发布,特别是前.后端一起上线发布,项目又特别多的时候. 例如你有10个项目,前后端 ...
- 设置Anaconda启动jupyter的默认目录
要解决的问题:安装好Anaconda后打开jupyter总是会自动跳到c:下的用户目录,通过以下方法可以修改其默认打开的目录 吐槽:竟然没有设置默认打开目录的选项,只能通过修改配置文件完成,让人不爽. ...