JS拖拽原理
实现拖拽效果主要跟鼠标的三个事件有关:
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拖拽原理的更多相关文章
- js拖拽原理和碰撞原理
拖拽的原理onmousedown 选择元素onmousemove 移动元素onmouseup 释放元素 1:如果拖拽的时候有文字:被选中,会产生问题原因:当鼠标按下的时如果页面中有文字或者图片被选中的 ...
- js拖拽原理及简单实现(渣渣自学)
第一步 首先简单分析下需求吧,我们就是想实现鼠标拖拽带颜色的方块时,让方块停留在鼠标松开的位置,需要计算的就是拖拽前的坐标和拖拽后的坐标,鼠标移动后相对于原位置的偏移量=目标元素的偏移量,根据这个等式 ...
- js拖拽效果的实现及原理
元素拖拽分成3个步骤:按下鼠标,移动鼠标,松开鼠标. 拖拽原理:按下拖拽元素后开始监听文档中鼠标移动事件,然后再监听鼠标松开事件:鼠标移动时,元素div要随着鼠标一起移动,需要计算元素div位移的距离 ...
- 一步一步实现JS拖拽插件
js拖拽是常见的网页效果,本文将从零开始实现一个简单的js插件. 一.js拖拽插件的原理 常见的拖拽操作是什么样的呢?整过过程大概有下面几个步骤: 1.用鼠标点击被拖拽的元素 2.按住鼠标不放,移动鼠 ...
- 再谈React.js实现原生js拖拽效果
前几天写的那个拖拽,自己留下的疑问...这次在热心博友的提示下又修正了一些小小的bug,也加了拖拽的边缘检测部分...就再聊聊拖拽吧 一.不要直接操作dom元素 react中使用了虚拟dom的概念,目 ...
- React.js实现原生js拖拽效果及思考
一.起因&思路 不知不觉,已经好几天没写博客了...近来除了研究React,还做了公司官网... 一直想写一个原生js拖拽效果,又加上近来学react学得比较嗨.所以就用react来实现这个拖 ...
- js拖拽效果
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- 关于 JS 拖拽功能的冲突问题及解决方法
前言 我在之前写过关于 JS 拖拽的文章,实现方式和网上能搜到的方法大致相同,别无二致,但是在一次偶然的测试中发现,这种绑定事件的方式可能会和其它的拖拽事件产生冲突,由此产生了对于事件绑定的思考.本文 ...
- js拖拽分析
js拖拽分析 思路 1.三个鼠标事件,mousedown,mousemove,mouseup 2.可移动性absolute 3.边界限制 得到鼠标点击处和div边界的距离,然后得出top 和 left ...
随机推荐
- ios常用动画
// // CoreAnimationEffect.h // CoreAnimationEffect // // Created by VincentXue on 13-1-19. // Copyri ...
- VM使用标准交换机
1.新建模板: 网卡选择“未连接”,此处看不到“标准交换机”选项
- 【M13】以by reference 方式捕捉exceptions
1.catch语句的参数有三种方式:by pointer,by value,by reference. 2.首先考虑,by pointer.这意味着抛出端必须抛出一个对象的地址.那么问题来了: 如果这 ...
- ThinkPHP3.1快速入门(12)自动验证
自动验证是ThinkPHP模型层提供的一种数据验证方法,可以在使用create创建数据对象的时候自动进行数据验证. 验证规则 数据验证可以进行数据类型.业务规则.安全判断等方面的验证操作.数据验证有两 ...
- hdu 5495 LCS 水题
LCS Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=5495 Descr ...
- 金蝶KIS 13.0专业版破解方法破解安装流程 金蝶KIS 13.0专业版安装流程
金蝶KIS 13.0安装 1.先安装操作系统Windows server 2008 R2. 2.再安装SQL2008 R2. 3.再安装金蝶KIS 13.0专业版. 在安装时记住须要将系列号设置成为1 ...
- [Effective C++ --014]在资源管理类中小心copying行为
第一节 <背景> 条款13中讲到“资源取得的时机便是初始化时机”并由此引出“以对象管理资源”的概念.通常情况下使用std中的auto_ptr(智能指针)和tr1::shared_ptr(引 ...
- Languages
Languages A language class exists inside the system/Core folder, this class have 2 methods: load - L ...
- 会话状态Session解析以及原理分析
我们知道web网站在客户端存储数据有三种形式:1. Cookie 2. hidden(隐藏域) 3.QueryString 其中viewstate什么的都是通过第二种方式隐藏域存储滴. 客户端存储 ...
- javascript优化工具 Doloto
Doloto是“Download Time Optimizer”的简写.官方页面上说它对于大型复杂的AJAX应用尤其的有用,因为这些应用包含了大量的 JavaScript 代码.简单的说,它的工作原理 ...