模拟拖拽的原理:

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动画-模拟拖拽的更多相关文章

  1. javascript动画系列第一篇——模拟拖拽

    × 目录 [1]原理介绍 [2]代码实现 [3]代码优化[4]拖拽冲突[5]IE兼容 前面的话 从本文开始,介绍javascript动画系列.javascript本身是具有原生拖放功能的,但是由于兼容 ...

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

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

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

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

  4. 模拟拖拽图片 碰撞检测 DOM 鼠标事件 闭包

    <!doctype html><html lang="en"> <head> <meta charset="UTF-8" ...

  5. JavaScript:鼠标拖拽效果

    (之前的那个模板方法模式实在没搞懂...等几天再去研究8) 预览效果: 限制拖动范围在视口内.调整窗口时自动居中... <!DOCTYPE html> <html lang=&quo ...

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

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

  7. javascript实现的拖拽回放

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

  8. c++ 发送消息,模拟拖拽文件

    #include <ShlObj.h> BOOL SimulateDropFile(CString strFilePath) { }; wcstombs(szFile, strFilePa ...

  9. Javascript之盒子拖拽(跟随鼠标、边界限定、轨迹回放)

    本文通过拖拽案例,实现"跟随鼠标.边界限定.轨迹回放"三大效果: 完整代码中有详尽注释,故不再进行细致讲解: 对于案例中需要注意的重点或易错点问题,会总结在最后. 效果图(仅演示左 ...

随机推荐

  1. Sql Server系列:分区表操作

    1. 分区表简介 分区表在逻辑上是一个表,而物理上是多个表.从用户角度来看,分区表和普通表是一样的.使用分区表的主要目的是为改善大型表以及具有多个访问模式的表的可伸缩性和可管理性. 分区表是把数据按设 ...

  2. react-router 组件式配置与对象式配置小区别

    1. react-router 对象式配置 和 组件式配置    组件式配置(Redirect) ----对应---- 对象式配置(onEnter钩子) IndexRedirect -----对应-- ...

  3. npm 私有模块的管理使用

    你可以使用 NPM 命令行工具来管理你在 NPM 仓库的私有模块代码,这使得在项目中使用公共模块变的更加方便. 开始前的工作 你需要一个 2.7.0 以上版本的 npm ,并且需要有一个可以登陆 np ...

  4. Hawk 4.7 单步调试

    单步调试的意义 已经编写的工作流,可能会因为某些外界环境的变化而出错,此时需要排除错误,我们可以使用单步调试. 单步调试的本质,相当于只使用前n个模块,这样就能看到每个步骤下,流的改变. 例子 还是上 ...

  5. ASP.NET Core 1.0 使用 Dapper 操作 MySql(包含事务)

    操作 MySql 数据库使用MySql.Data程序包(MySql 开发,其他第三方可能会有些问题). project.json 代码: { "version": "1. ...

  6. C#调用C++代码遇到的问题总结

    最近在开发服务后台的时候,使用c#调用了多个c++编写的dll,期间遇到了一系列的问题,经过一番努力最后都一一解决了,在此做个总结,方便以后参考,毕竟这些问题也都是很常见的,主要有以下问题: 类型对照 ...

  7. 【手记】注意BinaryWriter写string的小坑——会在string前加上长度前缀length-prefixed

    之前以为BinaryWriter写string会严格按构造时指定的编码(不指定则是无BOM的UTF8)写入string的二进制,如下面的代码: //将字符串"a"写入流,再拿到流的 ...

  8. jQuery可拖拽3D万花筒旋转特效

    这是一个使用了CSS3立体效果的强大特效,本特效使用jQuery跟CSS3 transform来实现在用户鼠标按下拖动时,环形图片墙可以跟随鼠标进行3D旋转动画. 效果体验:http://hovert ...

  9. 星浩资本快速发展引擎:IT就是生产力

    星浩资本成立于2010年,是一家涵盖私募基金.开发管理.商业与现代服务业三大业务范围的综合性管理公司,专注于投资中国首创.高成长性.高回报率的创新型城市综合体. 年轻的星浩资本在商业投资上有其独到的商 ...

  10. git基本操作

    一.在Windows平台上安装Git,可以下载一个msysGit的安装包,点击exe即可安装运行.安装包下载地址:https://git-for-windows.github.io/备注:git命令行 ...