JavaScript动画-模拟拖拽
模拟拖拽的原理:
x1等于div.offsetLeft
y1等于div.offsetTop
x2等于ev.clientX(ev表示event事件)
y2等于ev.clientY
当我们在方块上按下鼠标的时候,x2-x1即可确定。移动鼠标之后,我们用鼠标当前的位置即x4、y4减去x2-x1、y2-y1就可以得到方块现在的位置。
效果图:点击查看
代码:
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <title>Document</title>
- <style>
- #box{
- width: 100px;
- height: 100px;
- background: red;
- position: absolute;
- }
- </style>
- </head>
- <body>
- <div id="box"></div>
- <script type="text/javascript">
- var oBox = document.getElementById('box');
- oBox.onmousedown = function(ev){
- // 鼠标按下
- var ev = ev || event;
- // 获取鼠标离div得距离
- var mouseBoxleft = ev.clientX - this.offsetLeft;
- var mouseBoxTop = ev.clientY - this.offsetTop;
- oBox.onmousemove = function(ev){
- // 鼠标按下左键并移动
- var ev = ev || event;
- // 设置div移动时,它的位置
- oBox.style.left = ev.clientX - mouseBoxleft + 'px';
- oBox.style.top = ev.clientY - mouseBoxleft + 'px';
- }
- oBox.onmouseup = function(){
- // 鼠标左键抬起
- oBox.onmousemove = oBox.onmouseup = null;
- }
- }
- </script>
- </body>
- </html>
优化代码:
【1】鼠标移动快的时候,鼠标会移出方块,这时方块就不会再跟随鼠标动了。
解决办法:就是将onmousemove和onmouseup加到document对象上
效果:点击查看
代码:
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <title>Document</title>
- <style>
- #box{
- width: 100px;
- height: 100px;
- background: red;
- position: absolute;
- }
- </style>
- </head>
- <body>
- <div id="box"></div>
- <script>
- var oBox = document.getElementById('box');
- oBox.onmousedown = function(ev){
- // 鼠标按下
- var ev = ev || event;
- // 获取鼠标离div得距离
- var mouseBoxleft = ev.clientX - this.offsetLeft;
- var mouseBoxTop = ev.clientY - this.offsetTop;
- document.onmousemove = function(ev){
- // 鼠标按下左键并移动
- var ev = ev || event;
- // 设置div移动时,它的位置
- oBox.style.left = ev.clientX - mouseBoxleft + 'px';
- oBox.style.top = ev.clientY - mouseBoxleft + 'px';
- }
- document.onmouseup = function(){
- // 鼠标左键抬起
- document.onmousemove = document.onmouseup = null;
- }
- }
- </script>
- </body>
- </html>
【2】当要拖动的方块中有文字时会触发浏览器的默认行为
解决办法:1、使用return false添加到onmousedown事件中阻止浏览器的默认行为(IE除外)
2、使用全局捕获(IE)
1、使用return false添加到onmousedown事件中阻止浏览器的默认行为(IE除外)
效果:点击查看
代码:
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <title>Document</title>
- <style>
- #box{
- width: 100px;
- height: 100px;
- background: red;
- position: absolute;
- top: 0;
- left: 0;
- }
- </style>
- </head>
- <body>
- <div id="box">模拟拖拽</div>
- <script>
- var oBox = document.getElementById('box');
- oBox.onmousedown = function(ev){
- // 鼠标按下
- var ev = ev || event;
- // 获取鼠标离div得距离
- var mouseBoxleft = ev.clientX - this.offsetLeft;
- var mouseBoxTop = ev.clientY - this.offsetTop;
- document.onmousemove = function(ev){
- // 鼠标按下左键并移动
- var ev = ev || event;
- // 设置div移动时,它的位置
- oBox.style.left = ev.clientX - mouseBoxleft + 'px';
- oBox.style.top = ev.clientY - mouseBoxleft + 'px';
- }
- document.onmouseup = function(){
- // 鼠标左键抬起
- document.onmousemove = document.onmouseup = null;
- }
- // 阻止默认行为
- return false;
- }
- </script>
- </body>
- </html>
2、使用全局捕获(IE)
全局捕获:当我们给一个元素这只全局捕获后,改元素会监听后续发生的所有事件,当有事件发生的时候就会触发改元素的事件
举个栗子:点击查看
代码:
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <title>Document</title>
- </head>
- <body>
- <input type="button" id="button1" value="弹出1" />
- <input type="button" id="button2" value="弹出2" />
- <script type="text/javascript">
- window.onload = function(){
- var Btn1 = document.getElementById('button1');
- var Btn2 = document.getElementById('button2');
- Btn1.setCapture();
- Btn1.onclick = function(){
- alert(1);
- }
- Btn2.onclick = function(){
- alert(2);
- }
- }
- </script>
- </body>
- </html>
给Btn1设置了全局捕获之后,即使我们点击了Btn2还是会触发Btn1的点击事件
在模拟拖拽中,给要拖拽的方块onmousedown添加全局捕获然后再onmouseup中取消全局捕获
效果:点击查看
代码:
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <title>Document</title>
- <style>
- #box{
- width: 100px;
- height: 100px;
- background: red;
- position: absolute;
- }
- </style>
- </head>
- <body>
- <div id="box">模拟拖拽</div>
- <script>
- var oBox = document.getElementById('box');
- oBox.onmousedown = function(ev){
- // 鼠标按下
- var ev = ev || event;
- // 获取鼠标离div得距离
- var mouseBoxleft = ev.clientX - this.offsetLeft;
- var mouseBoxTop = ev.clientY - this.offsetTop;
- // IE浏览器,全局捕获
- if(oBox.setCapture){
- oBox.setCapture();
- }
- document.onmousemove = function(ev){
- // 鼠标按下左键并移动
- var ev = ev || event;
- // 设置div移动时,它的位置
- oBox.style.left = ev.clientX - mouseBoxleft + 'px';
- oBox.style.top = ev.clientY - mouseBoxleft + 'px';
- }
- document.onmouseup = function(){
- // 鼠标左键抬起
- document.onmousemove = document.onmouseup = null;
- //IE下,释放全局捕获 releaseCapture();
- if ( oBox.releaseCapture ) {
- oBox.releaseCapture();
- }
- }
- // 阻止默认行为
- return false;
- }
- </script>
- </body>
- </html>
【3】封装模拟拖拽函数
效果:点击查看
代码:
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <title>Document</title>
- <style>
- #box{
- width: 100px;
- height: 100px;
- background: red;
- position: absolute;
- }
- </style>
- </head>
- <body>
- <div id="box">模拟拖拽</div>
- <script>
- var oBox = document.getElementById('box');
- drag(oBox);
- function drag(obj){
- obj.onmousedown = function(ev){
- // 鼠标按下
- var ev = ev || event;
- // 获取鼠标离div得距离
- var mouseBoxleft = ev.clientX - this.offsetLeft;
- var mouseBoxTop = ev.clientY - this.offsetTop;
- // IE浏览器,全局捕获
- if(obj.setCapture){
- obj.setCapture();
- }
- document.onmousemove = function(ev){
- // 鼠标按下左键并移动
- var ev = ev || event;
- // 设置div移动时,它的位置
- obj.style.left = ev.clientX - mouseBoxleft + 'px';
- obj.style.top = ev.clientY - mouseBoxleft + 'px';
- }
- document.onmouseup = function(){
- // 鼠标左键抬起
- document.onmousemove = document.onmouseup = null;
- //IE下,释放全局捕获 releaseCapture();
- if ( obj.releaseCapture ) {
- obj.releaseCapture();
- }
- }
- // 阻止默认行为
- return false;
- }
- }
- </script>
- </body>
- </html>
JavaScript动画-模拟拖拽的更多相关文章
- javascript动画系列第一篇——模拟拖拽
× 目录 [1]原理介绍 [2]代码实现 [3]代码优化[4]拖拽冲突[5]IE兼容 前面的话 从本文开始,介绍javascript动画系列.javascript本身是具有原生拖放功能的,但是由于兼容 ...
- 每天一个JavaScript实例-html5拖拽
<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content ...
- day25—JavaScript实现文件拖拽上传案例实践
转行学开发,代码100天——2018-04-10 今天记录一个利用JavaScript实现文件拖拽上传到浏览器,后天将文件打开的小案例. 基本功能:1点击添加文件 2 文件拖拽添加 html: < ...
- 模拟拖拽图片 碰撞检测 DOM 鼠标事件 闭包
<!doctype html><html lang="en"> <head> <meta charset="UTF-8" ...
- JavaScript:鼠标拖拽效果
(之前的那个模板方法模式实在没搞懂...等几天再去研究8) 预览效果: 限制拖动范围在视口内.调整窗口时自动居中... <!DOCTYPE html> <html lang=&quo ...
- JavaScript实现图片拖拽、粘贴上传
前些日子为老婆做了一个web管理商品的工具,因为商品的图片比较多并且还需要剪裁图,为了上传图片方便加了一个拖拽.粘贴上传的功能. 我已经把代码整理出来放到GitHub上了,有兴趣的朋友可以下来玩玩. ...
- javascript实现的拖拽回放
这个功能很简单,直接贴代码啊: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "ht ...
- c++ 发送消息,模拟拖拽文件
#include <ShlObj.h> BOOL SimulateDropFile(CString strFilePath) { }; wcstombs(szFile, strFilePa ...
- Javascript之盒子拖拽(跟随鼠标、边界限定、轨迹回放)
本文通过拖拽案例,实现"跟随鼠标.边界限定.轨迹回放"三大效果: 完整代码中有详尽注释,故不再进行细致讲解: 对于案例中需要注意的重点或易错点问题,会总结在最后. 效果图(仅演示左 ...
随机推荐
- C#异步编程(一)
异步编程简介 前言 本人学习.Net两年有余,是第一次写博客,虽然写的很认真,当毕竟是第一次,肯定会有很多不足之处, 希望大家照顾照顾新人,有错误之处可以指出来,我会虚心接受的. 何谓异步 与同步相对 ...
- [PHP内核探索]PHP中的哈希表
在PHP内核中,其中一个很重要的数据结构就是HashTable.我们常用的数组,在内核中就是用HashTable来实现.那么,PHP的HashTable是怎么实现的呢?最近在看HashTable的数据 ...
- Socket聊天程序——服务端
写在前面: 昨天在博客记录自己抽空写的一个Socket聊天程序的初始设计,那是这个程序的整体设计,为了完整性,今天把服务端的设计细化记录一下,首页贴出Socket聊天程序的服务端大体设计图,如下图: ...
- .NET 基础 一步步 一幕幕[面向对象之方法、方法的重载、方法的重写、方法的递归]
方法.方法的重载.方法的重写.方法的递归 方法: 将一堆代码进行重用的一种机制. 语法: [访问修饰符] 返回类型 <方法名>(参数列表){ 方法主体: } 返回值类型:如果不需要写返回值 ...
- ASP.NET Core应用针对静态文件请求的处理[1]: 以Web的形式发布静态文件
虽然ASP.NET Core是一款"动态"的Web服务端框架,但是在很多情况下都需要处理针对静态文件的请求,最为常见的就是这对JavaScript脚本文件.CSS样式文件和图片文件 ...
- SQL Server-聚焦计算列持久化(二十一)
前言 上一节我们结束了Hash Match Aggregate和Stream Aggregate的讲解,本系列我们来讲讲关于SQL Server中的计算列问题,简短的内容,深入的理解,Always t ...
- 前端性能优化的另一种方式——HTTP2.0
最近在读一本书叫<web性能权威指南>谷歌公司高性能团队核心成员的权威之作. 一直听说HTTP2.0,对此也仅仅是耳闻,没有具体研读过,这次正好有两个篇章,分别讲HTTP1.1和HTTP2 ...
- ASP.NET Core 中文文档 第四章 MVC(4.4)依赖注入和控制器
原文: Dependency Injection and Controllers 作者: Steve Smith 翻译: 刘浩杨 校对: 孟帅洋(书缘) ASP.NET Core MVC 控制器应通过 ...
- iOS之计算上次日期距离现在多久, 如 xx 小时前、xx 分钟前等
/** * 计算上次日期距离现在多久 * * @param lastTime 上次日期(需要和格式对应) * @param format1 上次日期格式 * @para ...
- Android之ContentProvider数据存储
一.ContentProvider保存数据介绍 一个程序可以通过实现一个ContentProvider的抽象接口将自己的数据完全暴露出去,而且ContentProvider是以类似数据库中表的方式将数 ...