实现拖拽效果主要跟鼠标的三个事件有关:    

    onmousedown : 选择要拖拽的元素
    onmousemove : 移动元素
    onmouseup : 释放元素

三个事件的关系:
obj.onmousedown = function(ev){
var ev = ev||event; var disX = ev.clientX - this.offsetLeft;
var disY = ev.clientY - this.offsetTop; obj.ommousemove = function(ev){ var ev = ev||event;
obj.style.left = ev.clientX - disX + 'px';
obj.style.top = ev.clientY - disY + 'px'; }
obj.onmouseup = function(){
obj.onmousemove = null;
} }

  以上代码是实现拖拽的最基本方法,但是如果鼠标移动过快脱离obj,移动就会失去效果,所以移动事件(onmousemove)应该绑定在document上面,同时onmouseup也应该绑定在document上:

obj.onmousedown = function(ev){
var ev = ev||event; var disX = ev.clientX - this.offsetLeft;
var disY = ev.clientY - this.offsetTop; document.ommousemove = function(ev){ var ev = ev||event;
obj.style.left = ev.clientX - disX + 'px';
obj.style.top = ev.clientY - disY + 'px'; }
document.onmouseup = function(){
obj.onmousemove = null;
} }

 问题 拖拽的时候,如果有文字被选中,会产生问题

原因:当鼠标按下的时候,如果页面中有文字被选中,那么会触发浏览器默认拖拽文字的效果 ,拖拽图片也是一样,会类似复制一份出来一样,解决办法跟文字一样

  解决:
    标准:  阻止默认行为
    非标准ie:  设置全局捕获setCapture()(跟事件的捕获不是一个概念)

全局捕获:

例如:页面有两个input,点击input1弹出1,点击input2弹出2 ,如果我们给input1设置全局捕获,让后续的所有操作截取到input1上面,那么此时无论点击input2还是点击文档的任何地方,包括点击桌面,

  input1都会将这些点击事件截取到自己身上来执行自己的click事件,就是弹出1,这就是设置全局捕获的一个效果。

<script>
window.onload = function() { var aInput = document.getElementsByTagName('input'); aInput[0].setCapture(); //设置全局捕获 ,当我们给一个元素设置全局捕获以后,那么这个元素就会监听后续发生的所有事件,当有事件发生的时候,就会被当前设置了全局捕获的元素所触发 /*
ie : 有,并且有效果
ff : 有,但是没效果
chrome : 没有setCapture()
*/ aInput[0].onclick = function() {
alert(1);
} aInput[1].onclick = function() {
alert(2);
} }
</script>
</head> <body>
<input type="button" value="按钮一" />
<input type="button" value="按钮二" />
</body>
</html>  

  但是全局捕获也是有兼容性的,

     ie : 有,并且有效果
ff : 有,但是没效果
chrome : 没有setCapture() 所以用的时候首先要判断元素有没有setCapture()
          if ( obj.setCapture ) {
oDiv.setCapture();
  }
  当鼠标抬起的时候也要释放全局捕获 releaseCapture(); 所以拖拽的时候,如果有文字被选中,我们可以阻止文字的默认事件或者是利用全局捕获将所有的事件都截取到obj上,这样文字不会触发事件:

<style>
#div1 {width: 100px; height: 100px; background: red; position: absolute;}
</style>
<script>
window.onload = function() { var oDiv = document.getElementById('div1'); oDiv.onmousedown = function(ev) {
var ev = ev || event; var disX = ev.clientX - this.offsetLeft;
var disY = ev.clientY - this.offsetTop; if ( oDiv.setCapture ) {
oDiv.setCapture();
} document.onmousemove = function(ev) {
var ev = ev || event; oDiv.style.left = ev.clientX - disX + 'px';
oDiv.style.top = ev.clientY - disY + 'px';
} document.onmouseup = function() {
document.onmousemove = document.onmouseup = null;
//释放全局捕获 releaseCapture();
if ( oDiv.releaseCapture ) {
oDiv.releaseCapture();
}
} return false; } }
</script>
</head> <body>
jafldsfjdsjfkl
<div id="div1"></div>
</body>
</html>

 这就是拖拽的一个最基本的实现。

拖拽的封装 drag(obj);

<style>
#div1 {width: 100px; height: 100px; background: red; position: absolute;}
#img1 { position: absolute;}
</style>
<script>
window.onload = function() { var oDiv = document.getElementById('div1');
var oImg = document.getElementById('img1'); drag(oImg);
drag(oDiv);

function drag(obj) { obj.onmousedown = function(ev) {
var ev = ev || event; var disX = ev.clientX - this.offsetLeft;
var disY = ev.clientY - this.offsetTop; if ( obj.setCapture ) {
obj.setCapture();
} document.onmousemove = function(ev) {
var ev = ev || event; obj.style.left = ev.clientX - disX + 'px';
obj.style.top = ev.clientY - disY + 'px';
} document.onmouseup = function() {
document.onmousemove = document.onmouseup = null;
//释放全局捕获 releaseCapture();
if ( obj.releaseCapture ) {
obj.releaseCapture();
}
} return false; } } }
</script>
</head> <body>
<div id="div1"></div>
<img src="1.jpg" id="img1" />
</body>
</html>  

限制范围的拖拽: 先判断值,再赋值。
<style>
#div1 {width: 100px; height: 100px; background: red; position: absolute;}
#img1 { position: absolute;}
</style>
<script>
window.onload = function() { var oDiv = document.getElementById('div1');
var oImg = document.getElementById('img1'); drag(oImg); drag(oDiv); function drag(obj) { obj.onmousedown = function(ev) {
var ev = ev || event; var disX = ev.clientX - this.offsetLeft;
var disY = ev.clientY - this.offsetTop; if ( obj.setCapture ) {
obj.setCapture();
} document.onmousemove = function(ev) {
var ev = ev || event; var L = ev.clientX - disX;
var T = ev.clientY - disY; if ( L < 0 ) {
L = 0;
} else if ( L > document.documentElement.clientWidth - obj.offsetWidth ) {
L = document.documentElement.clientWidth - obj.offsetWidth;
} if ( T < 0 ) {
T = 0;
} else if ( T > document.documentElement.clientHeight - obj.offsetHeight ) {
T = document.documentElement.clientHeight - obj.offsetHeight;
} obj.style.left = L + 'px';
obj.style.top = T + 'px'; } document.onmouseup = function() {
document.onmousemove = document.onmouseup = null;
if ( obj.releaseCapture ) {
obj.releaseCapture();
}
} return false; } } }
</script>
</head> <body>
<div id="div1"></div>
<img src="1.jpg" id="img1" />
</body>
</html>

 有一种磁性吸附的效果:

                   if ( L < ) {
L = 0;
} else if ( L > document.documentElement.clientWidth - obj.offsetWidth ) {
L = document.documentElement.clientWidth - obj.offsetWidth;
}

碰撞检测实例

<style>
#div1 {width: 100px; height: 100px; background: red; position: absolute; z-index: 2;}
#img1 { position: absolute; left: 500px; top: 200px;}
</style>
<script>
window.onload = function() { var oDiv = document.getElementById('div1');
var oImg = document.getElementById('img1'); drag(oDiv); function drag(obj) { obj.onmousedown = function(ev) {
var ev = ev || event; var disX = ev.clientX - this.offsetLeft;
var disY = ev.clientY - this.offsetTop; if ( obj.setCapture ) {
obj.setCapture();
} document.onmousemove = function(ev) {
var ev = ev || event; var L = ev.clientX - disX;
var T = ev.clientY - disY; var L1 = L;
var R1 = L + obj.offsetWidth;
var T1 = T;
var B1 = T + obj.offsetHeight; var L2 = oImg.offsetLeft;
var R2 = L2 + oImg.offsetWidth;
var T2 = oImg.offsetTop;
var B2 = T2 + oImg.offsetHeight; if ( R1 < L2 || L1 > R2 || B1 < T2 || T1 > B2 ) {
oImg.src = '1.jpg';
} else {
oImg.src = '2.jpg';
} obj.style.left = L + 'px';
obj.style.top = T + 'px'; } document.onmouseup = function() {
document.onmousemove = document.onmouseup = null;
if ( obj.releaseCapture ) {
obj.releaseCapture();
}
} return false; } } }
</script>
</head> <body>
<div id="div1"></div>
<img src="1.jpg" id="img1" />
</body>
</html>

  

  

 

JS拖拽原理的更多相关文章

  1. js拖拽原理和碰撞原理

    拖拽的原理onmousedown 选择元素onmousemove 移动元素onmouseup 释放元素 1:如果拖拽的时候有文字:被选中,会产生问题原因:当鼠标按下的时如果页面中有文字或者图片被选中的 ...

  2. js拖拽原理及简单实现(渣渣自学)

    第一步 首先简单分析下需求吧,我们就是想实现鼠标拖拽带颜色的方块时,让方块停留在鼠标松开的位置,需要计算的就是拖拽前的坐标和拖拽后的坐标,鼠标移动后相对于原位置的偏移量=目标元素的偏移量,根据这个等式 ...

  3. js拖拽效果的实现及原理

    元素拖拽分成3个步骤:按下鼠标,移动鼠标,松开鼠标. 拖拽原理:按下拖拽元素后开始监听文档中鼠标移动事件,然后再监听鼠标松开事件:鼠标移动时,元素div要随着鼠标一起移动,需要计算元素div位移的距离 ...

  4. 一步一步实现JS拖拽插件

    js拖拽是常见的网页效果,本文将从零开始实现一个简单的js插件. 一.js拖拽插件的原理 常见的拖拽操作是什么样的呢?整过过程大概有下面几个步骤: 1.用鼠标点击被拖拽的元素 2.按住鼠标不放,移动鼠 ...

  5. 再谈React.js实现原生js拖拽效果

    前几天写的那个拖拽,自己留下的疑问...这次在热心博友的提示下又修正了一些小小的bug,也加了拖拽的边缘检测部分...就再聊聊拖拽吧 一.不要直接操作dom元素 react中使用了虚拟dom的概念,目 ...

  6. React.js实现原生js拖拽效果及思考

    一.起因&思路 不知不觉,已经好几天没写博客了...近来除了研究React,还做了公司官网... 一直想写一个原生js拖拽效果,又加上近来学react学得比较嗨.所以就用react来实现这个拖 ...

  7. js拖拽效果

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  8. 关于 JS 拖拽功能的冲突问题及解决方法

    前言 我在之前写过关于 JS 拖拽的文章,实现方式和网上能搜到的方法大致相同,别无二致,但是在一次偶然的测试中发现,这种绑定事件的方式可能会和其它的拖拽事件产生冲突,由此产生了对于事件绑定的思考.本文 ...

  9. js拖拽分析

    js拖拽分析 思路 1.三个鼠标事件,mousedown,mousemove,mouseup 2.可移动性absolute 3.边界限制 得到鼠标点击处和div边界的距离,然后得出top 和 left ...

随机推荐

  1. AD新建用户、组、OU

    #新建用户 import-csv d:\AD\Users.csv | Foreach {New-ADUser -Name $_.Name -Path $_.Path -samAccountName $ ...

  2. mysql下命令行执行sql脚本

    1. 登录mysql mysql -uroot -p 2. 执行脚本 mysql>use dbname; mysql>source /home/db/xx.sql

  3. 教你如何选择Android游戏引擎

    我们进行Android游戏开发时选择游戏引擎是必须的,但是该如何选择呢?哪个Android游戏引擎更加适合自己呢?本文就提供了三个游戏引擎的对比说明,阐述了它们各自的特点,为大家选择引擎提供了参照. ...

  4. [ACM] 最短路算法整理(bellman_ford , SPFA , floyed , dijkstra 思想,步骤及模板)

    以杭电2544题目为例 最短路 Problem Description 在每年的校赛里,全部进入决赛的同学都会获得一件非常美丽的t-shirt. 可是每当我们的工作人员把上百件的衣服从商店运回到赛场的 ...

  5. PAT 1012

    1012. The Best Rank (25) To evaluate the performance of our first year CS majored students, we consi ...

  6. GCD多线程

    GCD本质线程自动管理指令包 GCD优点: 1.GCD 本身自带有线程锁的效果,能通过推迟昂贵计算任务并在后台运行它们来改善应用的响应性能. 2.GCD 提供了更易于使用的并发模型(效果方面类似于对锁 ...

  7. 一个响应式数据库框架SQLBrite,完美解决数据库和UI的同步更新!

    相信小伙伴们在开发中或多或少都可能遇到过这样的问题:打开一个应用后,为了快速响应,先将数据库中的数据呈现给用户,然后再去网络上请求数据,请求成功之后将数据缓存至数据库,同时更新UI,但是我们经常会这样 ...

  8. Android(java)学习笔记136:Java类初始化顺序

    Java类中初试化的顺序: 由此得出Java普通类初始化顺序结论: 静态变量 静态初始化块 变量 初始化块 构造器 由此得出Java继承类初始化顺序结论:     1 .继承体系的所有静态成员初始化( ...

  9. 通过代码设置button中文字的对齐方式

    // button.titleLabel.textAlignment = NSTextAlignmentLeft; 这句无效 button.contentHorizontalAlignment = U ...

  10. Excel导入导出帮助类

    /// <summary>    /// Excel导入导出帮助类    /// 记得引入 NPOI    /// 下载地址   http://npoi.codeplex.com/rele ...