本文通过拖拽案例,实现“跟随鼠标、边界限定、轨迹回放”三大效果;

完整代码中有详尽注释,故不再进行细致讲解;

对于案例中需要注意的重点或易错点问题,会总结在最后。

效果图(仅演示左、上边界限定)

完整代码

<!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之盒子拖拽(跟随鼠标、边界限定、轨迹回放)的更多相关文章

  1. 每天一个JavaScript实例-html5拖拽

    <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content ...

  2. day25—JavaScript实现文件拖拽上传案例实践

    转行学开发,代码100天——2018-04-10 今天记录一个利用JavaScript实现文件拖拽上传到浏览器,后天将文件打开的小案例. 基本功能:1点击添加文件 2 文件拖拽添加 html: < ...

  3. day23—JavaScript实现DIV盒子拖拽(原生方式)

    转行学开发,代码100天——2018-04-08 <!doctype html> <html> <head> <meta charset="utf- ...

  4. JavaScript动画-模拟拖拽

    模拟拖拽的原理: x1等于div.offsetLeft y1等于div.offsetTop x2等于ev.clientX(ev表示event事件) y2等于ev.clientY 当我们在方块上按下鼠标 ...

  5. QTGraphics-View拖拽以及鼠标指针操作

    因为QGraphicsView继承自QWidget,它也提供了像QWidget那样的拖拽功能. 另外,为了方便,Graphics View框架也为场景以及每个item提供拖拽支持.当视图接收到拖拽事件 ...

  6. JavaScript实现图片拖拽、粘贴上传

    前些日子为老婆做了一个web管理商品的工具,因为商品的图片比较多并且还需要剪裁图,为了上传图片方便加了一个拖拽.粘贴上传的功能. 我已经把代码整理出来放到GitHub上了,有兴趣的朋友可以下来玩玩. ...

  7. javascript实现的拖拽回放

    这个功能很简单,直接贴代码啊: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "ht ...

  8. 超级简单的利用javascript实现文件拖拽事件

    1.效果图: 2.源码 <%@ page contentType="text/html;charset=UTF-8" language="java" %& ...

  9. JavaScript 面向对象的拖拽

    一.body <div id="box"></div> 二.css <style> #box { position: abaolute; top ...

随机推荐

  1. 使用 javascript 配置 nginx

    在上个月的 nginx.conf 2015 大会上, 官方宣布已经支持通过 javascript 代码来配置 nginx,并把这个实现称命名为--nginscript.使用 nginscript,可以 ...

  2. LNMP环境搭建--Centos7

    LNMP环境搭建--Centos7 | 刘鹏--博客 盒子 盒子 博客 分类 搜索 文章目录 在Centos7环境安装LAMP环境,备忘哈哈. 准备 首先去官网下载php,nginx 编译安装php ...

  3. Java版飞机订票系统

    关注微信公众号:Worldhello 回复 飞机订票系统 可获得系统源代码并可加群讨论交流 数据结构课程设计题目:          [飞机订票系统]            通过此系统可以实现如下功能 ...

  4. IP 数据报

    IP 数据报 1.IP 数据报的格式 一个 IP 数据报由首部和数据两部分组成.(数据报也可以说是数据包) 首部的前一部分是固定长度,共 20 字节,是所有 IP 数据报必须具有的. 在首部的固定部分 ...

  5. python爬虫之浅析验证码

    一.什么是验证码? 验证码(CAPTCHA)是“Completely Automated Public Turing test to tell Computers and Humans Apart”( ...

  6. 压力测试(二)-Jmeter基本介绍

    1.Jmeter基本介绍和使用场景 简介 1.压测不同的协议和应用 1) Web - HTTP, HTTPS (Java, NodeJS, PHP, ASP.NET, …) 2) SOAP / RES ...

  7. 7-10 jmu-python-异常-学生成绩处理基本版 (15 分)

    小明在帮老师处理数据,这些数据的第一行是n,代表有n行整数成绩需要统计.数据没有错误,则计算平均值(保留2位小数)并输出.数据有错误,直接停止处理,并且不进行计算. 注:该程序可以适当处理小错误,比如 ...

  8. OpenCV图像增强(python)

    为了得到更加清晰的图像我们需要通过技术对图像进行处理,比如使用对比度增强的方法来处理图像,对比度增强就是对图像输出的灰度级放大到指定的程度,获得图像质量的提升.本文主要通过代码的方式,通过OpenCV ...

  9. .NET微服务从0到1:服务注册与发现(Consul)

    目录 Consul搭建 基于Docker搭建Consul 基于Windows搭建Consul ServiceA集成Consul做服务注册 Ocelot集成Consul做服务发现 更多参考 Consul ...

  10. Java基础篇(02):特殊的String类,和相关扩展API

    本文源码:GitHub·点这里 || GitEE·点这里 一.String类简介 1.基础简介 字符串是一个特殊的数据类型,属于引用类型.String类在Java中使用关键字final修饰,所以这个类 ...