今天看到一篇写的很好的文章,摘抄如下:

思路

  1. 父盒子相对定位,子元素,也就是被拖拽的元素绝对定位
  2. 当鼠标在子元素中按下时,绑定鼠标移动事件,根据鼠标位置改变元素位置
    • 设置鼠标当前位置(offsetX,offsetY,这时和父的相对位置)为元素的中心位置
    • 移动时改变位置css中的left为offsetX...的位置
  3. 当鼠标离开时,解绑鼠标移动事件

实现过程(一)

css 部分

 .decision-box{
position: relative;
width: 1500px;
height: 600px;
border: 1px solid #000;
border-radius: 6px;
/*margin-left: -40px;*/
}
.item{
position: absolute;
width: 50px;
height: 30px;
background: green;
border-radius: 6px;
text-align: center;
line-height: 30px;
cursor: pointer;
left: 50px
}

html 部分

<div class="decision-box decision_box">
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
</div>

js 部分

 //鼠标按下,要在移动元素上按下
$(document).on('mousedown','.decision_box .item',function(e){
var ele = $(e.target);
$(document).on('mousemove','.decision_box',function(e){
//移动鼠标时改变元素位置
var x = e.offsetX,
y = e.offsetY;
ele.css({
left:x - 25 + 'px',
top:y - 15 + 'px'
});
e.stopPropagation();
});
e.stopPropagation();
});
//鼠标放开
$(document).on('mouseup',function(){
//解除鼠标移动事件
$(document).off('mousemove');
});

这时,发生了错误,元素一闪一闪的,位置不是一直跟着鼠标,在mousemove触发函数里打印一下位置,发现位置不一直是鼠标位置。原来是应为鼠标位置offsetX的原因。

关于鼠标位置

  • clientX 相对于可是窗口的距离
  • offsetX 相对于e.target元素的位置
  • pageX 相对于文档的左边缘
  • screenX 相对于屏幕的位置

原来offsetX是相对于e.target元素的位置。加入被拖拽元素宽高100px,当我点击100px,100px时,元素的中心位置变为100,100;此时offsetX又变为了50;这时offsetX又变回100;(以上数字只是数字,因为有移动)。如上,就形成了一闪一闪,之后鼠标会超过元素范围,这时,元素位置就在鼠标相对于本身和鼠标相对于父盒子之间切换。

那么怎么解决这个问题呢?我的思路是:

  • 使用其它鼠标位置,当点击元素时获取位置作为初始位置
  • 当移动时获取位置并求出相对位移,这个相对于位移也就是元素要移动的距离。

实现过程(二)

js 部分

//鼠标按下,要在移动元素上按下
$(document).on('mousedown','.decision_box .item',function(e){
console.log(parseInt($(e.target).css('left')))
var ele = $(e.target);
var initX = e.clientX,
initY = e.clientY,
itemX = parseInt(ele.css('left'));
itemY = parseInt(ele.css('top'));
$(document).on('mousemove','.decision_box',function(e){
//移动鼠标时改变元素位置
var curX = e.clientX,
curY = e.clientY;
ele.css({
left:itemX + (curX - initX) + 'px',
top:itemY + (curY - initY) + 'px'
});
e.stopPropagation();
});
e.stopPropagation();
});
//鼠标放开
$(document).on('mouseup',function(){
//解除鼠标移动事件
$(document).off('mousemove');
});

成功,可以拖动了,这时又遇上了一个问题,当拖动元素时,有其它文本别选中时,拖拽又出现了bug,这时就要用到下面面这两个属性

onselectstart = "return false";
onselect = "return false";
  • onselectstart事件不被input和textarea标签支持,而onselect事件只被input和textarea支持。
  • Firefox/Opera不支持onselectstart事件Firefox中可以使用CSS "-moz-user-select:none"属性来禁止文本选定
  • webkit浏览器可以使用“-khtml-user-select”,当然也可以使用onselectstart事件来阻止用户选定元素内文本,如下
<div onselectstart="return false">accc</div>

这个属性意思就是不让文本被选中。要做的就是当点击元素时,上这个属性,当放开鼠标时去掉这个属性(改成return true);

最后代码

  //鼠标按下,要在移动元素上按下
$(document).on('mousedown','.decision_box .item',function(e){
$('body').attr('onselectstart','return false');
console.log(parseInt($(e.target).css('left')))
var ele = $(e.target);
var initX = e.clientX,
initY = e.clientY,
itemX = parseInt(ele.css('left'));
itemY = parseInt(ele.css('top'));
$(document).on('mousemove','.decision_box',function(e){
//移动鼠标时改变元素位置
var curX = e.clientX,
curY = e.clientY;
ele.css({
left:itemX + (curX - initX) + 'px',
top:itemY + (curY - initY) + 'px'
});
e.stopPropagation();
});
e.stopPropagation();
});
//鼠标放开
$(document).on('mouseup',function(){
$('body').attr('onselectstart','return true');
//解除鼠标移动事件
$(document).off('mousemove');
});

这时,选中文本后再进行拖拽还有问题,(也可不解决)我暂时不知道;还有碰撞检测什么的也没加。待续......

https://www.jianshu.com/p/bd6e4f6122cf

div拖拽的问题的更多相关文章

  1. 实现Div拖拽

    直观的理解div拖拽:当鼠标对着可拖拽部分按住后并拖动,div会跟着鼠标一起运动,并且其运动空间限制在浏览器内部,当放开鼠标时,则div停止运动. 实现div拖拽需要三个重要的事件: (1)onmou ...

  2. html之div拖拽,html5拖拽

    html之div拖拽 http://www.w3school.com.cn/html5/html_5_draganddrop.asp

  3. 运用DIV拖拽实现resize和碰撞检测

    运用DIV拖拽实现resize和碰撞检测 Div由拖拽改变大小 演示demo 当我们运用html元素"textarea"写一个文本输入框时,浏览器会自动生成以下样式 用鼠标拖动右下 ...

  4. 纯js实现DIV拖拽

    写代码的时候遇到需要对绝对布局的div进行拖拽的功能,起初为了省事直接在网上扒拉了一番,看到大神张鑫旭的一篇文章<JavaScript实现最简单的拖拽效果>,便直接拿来使用(膜拜大神).但 ...

  5. 案例:简易的Div拖拽

    案例:简易的Div拖拽 鼠标移入Div区域后,按下鼠标左键,可以拖动Div移动;松开鼠标左键,Div拖动停止.同时要求Div不能拖出屏幕显示区域外. 拖拽原理:距离不变.三个事件(onmousedow ...

  6. html --- javascript --- div --- 拖拽方块

    当鼠标拖拽的很快时,光标会走出方块,所以把事件注册在了方块的父节点上, 如有疑问请参照:http://blog.csdn.net/a9529lty/article/details/2708171 使用 ...

  7. 原生js实现div拖拽+按下鼠标计时

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <style> ...

  8. 原生js实现div拖拽

    十分简单的效果. <!DOCTYPE html> <html> <head> <meta charset="utf-8"> < ...

  9. div拖拽缩放jquery插件编写——带8个控制点

    项目中需要对div进行拖拽缩放,需要有控制面板8个控制点的那种,原以为这么常见的效果应该能搜索到很多相关插件,然而可以完成拖拽的实繁,却找不到我想要的,还是自己动手丰衣足食吧 效果预览(只支持pc端) ...

  10. jquery实现div拖拽

    1.引入jquery1.8.3 ,模块拖拽js代码: //模块拖拽 $(function(){ var _move=false;//移动标记 var _x,_y;//鼠标离控件左上角的相对位置 $(& ...

随机推荐

  1. window.open弹窗阻止问题解决之道

    https://segmentfault.com/a/1190000015381923https://segmentfault.com/a/1190000014988094https://www.cn ...

  2. Intersection of Two Linked Lists(两个链表的第一个公共节点)

    来源:https://leetcode.com/problems/intersection-of-two-linked-lists Write a program to find the node a ...

  3. 《剑指offer》面试题19 二叉树的镜像 Java版

    书中方法:这道题目可能拿到手没有思路,我们可以在纸上画出简单的二叉树来找到规律.最后我们发现,镜像的实质是对于二叉树的所有节点,交换其左右子节点.搞清楚获得镜像的方法,这道题实际上就变成了一道二叉树遍 ...

  4. HDU 6649 Data Structure Problem(凸包+平衡树)

    首先可以证明,点积最值的点对都是都是在凸包上,套用题解的证明:假设里两个点都不在凸包上, 考虑把一个点换成凸包上的点(不动的那个点), 不管你是要点积最大还是最小, 你都可以把那个不动的点跟原点拉一条 ...

  5. 音频视频的播放的进度调整(以.net为例)

    Background:对于音视频在线播放,一些小应用是靠nginx处理访问视频.音频文件的请求,对外应用的一般会托管至各种云上使用相关的服务.前者存在巨大的安全隐患,后者会有一定的成本.有的时候还是需 ...

  6. 回溯---IP 地址划分

    IP 地址划分 93. Restore IP Addresses(Medium) Given "25525511135", return ["255.255.11.135 ...

  7. Spring、Spring MVC、Struts2、、优缺点整理(转)

    Spring 及其优点 大部分项目都少不了spring的身影,为什么大家对他如此青睐,而且对他的追捧丝毫没有减退之势呢 Spring是什么: Spring是一个轻量级的DI和AOP容器框架. 说它轻量 ...

  8. highcharts控制X刻度值整数调整

    function chartData() { var app_id = $('.app_id').attr('app_id'); var gener_id = $('.gener_id').attr( ...

  9. python面向对象--类的内置函数

    #isinstance(obj,cls)判断obj是否是类cls的实例 #issubclass(cls,cls1)判断cls是否是cls1的子类或派生类 class Foo: pass class B ...

  10. BZOJ-1907 树的路径覆盖 贪心

    题意:给一个n个点的树,求树的最小路径覆盖.(这个最小路径覆盖不能有重点) 解法:往图论方向想很久,想得太复杂了,其实直接贪心.这个大佬题解写得很好: https://blog.csdn.net/bl ...