Javascript之盒子拖拽(跟随鼠标、边界限定、轨迹回放)
本文通过拖拽案例,实现“跟随鼠标、边界限定、轨迹回放”三大效果;
完整代码中有详尽注释,故不再进行细致讲解;
对于案例中需要注意的重点或易错点问题,会总结在最后。
效果图(仅演示左、上边界限定)
完整代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>盒子拖拽</title>
<style>
body{
margin: 0;
padding: 0;
}
#box{
width: 100px;
height: 100px;
background: skyblue;
position: absolute;
/* 盒子在页面中的初始位置,可以随意设置 */
left: 200px;
top: 200px;
}
#btn{
display: inline-block;
width: 80px;
height: 30px;
font-size: 16px;
cursor: pointer;
outline: none;
}
</style>
</head>
<body>
<div id="box"><button id="btn">轨迹回放</button></div>
<script>
var box_ele = document.getElementById("box");
// 声明位置数组,用于记录盒子每次移动后的位置
var position_arr = [];
// 获取页面初始宽高,用于限定盒子移动边界
var screen_width = document.body.offsetWidth;
var screen_height = window.innerHeight; // 注意页面高度不能通过 document.body.offsetTop 获取
// 功能1:拖拽
// 设置变量记录鼠标的状态,鼠标按下时为true
var flag = false;
// 鼠标按下准备拖拽,记录鼠标按下时的位置
var mouse_x, mouse_y;
box_ele.addEventListener("mousedown", function(evt){
flag = true;
var e = evt || event;
mouse_x = e.offsetX; // 要以元素做参照物,用offset,不能用client
mouse_y = e.offsetY;
// 将盒子初始位置(盒子元素偏移量)记录在位置数组中
position_arr.push({
x : box_ele.offsetLeft,
y : box_ele.offsetTop
})
})
// 鼠标移动拖拽开始
// 事件绑定在document上,避免因鼠标移动速度太快超出盒子边界时盒子跟不上
document.addEventListener("mousemove", function(evt){
if(flag){
var e = evt || event;
// 声明盒子的位置
var box_left = e.clientX - mouse_x;
var box_top = e.clientY - mouse_y;
// 通过页面初始宽高和盒子宽高计算获得盒子移动的最大值
var move_width_max = screen_width - box_ele.offsetWidth;
var move_height_max = screen_height - box_ele.offsetHeight;
// 分别限定盒子移动的左右上下边界
box_left = box_left <= 0 ? 0 : box_left;
box_left = box_left >= move_width_max ? move_width_max : box_left;
box_top = box_top <= 0 ? 0 : box_top;
box_top = box_top >= move_height_max ? move_height_max : box_top;
// 将数据赋值给盒子从而在页面中渲染
box_ele.style.left = box_left + "px";
box_ele.style.top = box_top + "px";
// 若x或y方向移动距离大于5px,则将移动后的盒子位置记录到位置数组中(避免数组中保存数据过多,消耗性能)
if(box_left >= position_arr[position_arr.length - 1].x + 5 || box_top >= position_arr[position_arr.length - 1].y + 5){
position_arr.push({
x : box_left,
y : box_top
})
}
}
})
// 鼠标抬起拖拽停止
box_ele.addEventListener("mouseup", function(){
flag = false;
})
// 功能2:回放
var btn_ele = document.getElementById("btn");
var timer;
btn_ele.addEventListener("click", function(){
// 原思路:通过for循环遍历位置数组中的每一个位置
// 由于for循环执行太快,故使用定时器
timer = setInterval(function(){
// 每次取出位置数组中的最后一个元素位置
var last_position = position_arr.pop();
box_ele.style.left = last_position.x + "px";
box_ele.style.top = last_position.y + "px";
// 当移动到最后一个位置(即位置数组中数据为空)时,关闭定时器
if(position_arr.length === 0){
clearInterval(timer);
}
}, 50)
})
</script>
</body>
</html>
注意点
1、鼠标拖拽过程中的盒子位置需要通过 鼠标位置 - 初始时鼠标相对于元素位置
获取,即
box_left = e.clientX - mouse_x
box_top = e.clientY - mouse_y;
,
否则盒子会出现在鼠标的右下方。
2、初始的页面高度不能通过 document.body.offsetTop
获取,需要用 window.innerHeight
;
3、限制鼠标移动边界时,宽高方向的最大值需要通过 初始页面宽高 - 盒子宽高
获取,即
move_width_max = screen_width - box_ele.offsetWidth;
move_height_max = screen_height - box_ele.offsetHeight;
4、轨迹回放时,目标是位置数组中从后往前依次取出元素,最好的办法就是使用 pop()
。
5、注意定时器的关闭条件。position_arr.length === 0
Javascript之盒子拖拽(跟随鼠标、边界限定、轨迹回放)的更多相关文章
- 每天一个JavaScript实例-html5拖拽
<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content ...
- day25—JavaScript实现文件拖拽上传案例实践
转行学开发,代码100天——2018-04-10 今天记录一个利用JavaScript实现文件拖拽上传到浏览器,后天将文件打开的小案例. 基本功能:1点击添加文件 2 文件拖拽添加 html: < ...
- day23—JavaScript实现DIV盒子拖拽(原生方式)
转行学开发,代码100天——2018-04-08 <!doctype html> <html> <head> <meta charset="utf- ...
- JavaScript动画-模拟拖拽
模拟拖拽的原理: x1等于div.offsetLeft y1等于div.offsetTop x2等于ev.clientX(ev表示event事件) y2等于ev.clientY 当我们在方块上按下鼠标 ...
- QTGraphics-View拖拽以及鼠标指针操作
因为QGraphicsView继承自QWidget,它也提供了像QWidget那样的拖拽功能. 另外,为了方便,Graphics View框架也为场景以及每个item提供拖拽支持.当视图接收到拖拽事件 ...
- JavaScript实现图片拖拽、粘贴上传
前些日子为老婆做了一个web管理商品的工具,因为商品的图片比较多并且还需要剪裁图,为了上传图片方便加了一个拖拽.粘贴上传的功能. 我已经把代码整理出来放到GitHub上了,有兴趣的朋友可以下来玩玩. ...
- javascript实现的拖拽回放
这个功能很简单,直接贴代码啊: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "ht ...
- 超级简单的利用javascript实现文件拖拽事件
1.效果图: 2.源码 <%@ page contentType="text/html;charset=UTF-8" language="java" %& ...
- JavaScript 面向对象的拖拽
一.body <div id="box"></div> 二.css <style> #box { position: abaolute; top ...
随机推荐
- 使用 javascript 配置 nginx
在上个月的 nginx.conf 2015 大会上, 官方宣布已经支持通过 javascript 代码来配置 nginx,并把这个实现称命名为--nginscript.使用 nginscript,可以 ...
- LNMP环境搭建--Centos7
LNMP环境搭建--Centos7 | 刘鹏--博客 盒子 盒子 博客 分类 搜索 文章目录 在Centos7环境安装LAMP环境,备忘哈哈. 准备 首先去官网下载php,nginx 编译安装php ...
- Java版飞机订票系统
关注微信公众号:Worldhello 回复 飞机订票系统 可获得系统源代码并可加群讨论交流 数据结构课程设计题目: [飞机订票系统] 通过此系统可以实现如下功能 ...
- IP 数据报
IP 数据报 1.IP 数据报的格式 一个 IP 数据报由首部和数据两部分组成.(数据报也可以说是数据包) 首部的前一部分是固定长度,共 20 字节,是所有 IP 数据报必须具有的. 在首部的固定部分 ...
- python爬虫之浅析验证码
一.什么是验证码? 验证码(CAPTCHA)是“Completely Automated Public Turing test to tell Computers and Humans Apart”( ...
- 压力测试(二)-Jmeter基本介绍
1.Jmeter基本介绍和使用场景 简介 1.压测不同的协议和应用 1) Web - HTTP, HTTPS (Java, NodeJS, PHP, ASP.NET, …) 2) SOAP / RES ...
- 7-10 jmu-python-异常-学生成绩处理基本版 (15 分)
小明在帮老师处理数据,这些数据的第一行是n,代表有n行整数成绩需要统计.数据没有错误,则计算平均值(保留2位小数)并输出.数据有错误,直接停止处理,并且不进行计算. 注:该程序可以适当处理小错误,比如 ...
- OpenCV图像增强(python)
为了得到更加清晰的图像我们需要通过技术对图像进行处理,比如使用对比度增强的方法来处理图像,对比度增强就是对图像输出的灰度级放大到指定的程度,获得图像质量的提升.本文主要通过代码的方式,通过OpenCV ...
- .NET微服务从0到1:服务注册与发现(Consul)
目录 Consul搭建 基于Docker搭建Consul 基于Windows搭建Consul ServiceA集成Consul做服务注册 Ocelot集成Consul做服务发现 更多参考 Consul ...
- Java基础篇(02):特殊的String类,和相关扩展API
本文源码:GitHub·点这里 || GitEE·点这里 一.String类简介 1.基础简介 字符串是一个特殊的数据类型,属于引用类型.String类在Java中使用关键字final修饰,所以这个类 ...