原文来自:
http://www.cainiao8.com/web/js_examples/27_tuozhuai6.html
在实际应用拖拽的时候发现自己犯了两个错误,都是当文档内容多余一个屏幕的时候才会出现。
错误一,绝对位置
刚开始非常不解为什么拖拽需要获得鼠标相对文档的绝对位置,我之前写的代码也都是仅仅使用clientX和clientY实现的,这两个属性是相对浏览器的,没有将文档的滚动计算在内。因此在内容超过一页的时候,如果用户使用鼠标拖拽元素,不会有问题。但是如果用户采用边拖拽边滚滚动条的方式就会造成文档滚动部分没有被计算在内。测试了一下,豆瓣、百度空间、MSN Space的拖拽都不会有这个问题。
总之,应该使用元素相对文档的绝对位置。
错误二,没有更新鼠标位置和元素位置
下面是我刚开始想出来的拖拽实现方法,不过有一个严重的问题,就是在鼠标移动的时候不会动态地更新鼠标当前位置以及元素当前位置。但是如果我们使用相对位置的时候这个问题不会得到暴露。
拖拽状态 = 0
鼠标在元素上按下的时候{
拖拽状态 = 1
记录下鼠标的x和y坐标
记录下元素的x和y坐标
}
鼠标在元素上移动的时候{
如果拖拽状态是0就什么也不做。
如果拖拽状态是1,那么
元素y = 现在鼠标y - 原来鼠标y + 原来元素y
元素x = 现在鼠标x - 原来鼠标x + 原来元素x
}
鼠标在任何时候放开的时候{
拖拽状态 = 0
}
应该修改为:
拖拽状态 = 0
鼠标在元素上按下的时候{
拖拽状态 = 1
记录下鼠标的x和y坐标
记录下元素的x和y坐标
}
鼠标在元素上移动的时候{
如果拖拽状态是0就什么也不做。
如果拖拽状态是1,那么
元素y = 现在鼠标y - 原来鼠标y + 原来元素y
元素x = 现在鼠标x - 原来鼠标x + 原来元素x
更新元素坐标的记录!
更新鼠标坐标的记录!
}
鼠标在任何时候放开的时候{
拖拽状态 = 0
}
找到问题所在之后,代码的修改就比较简单了。最后的代码如下:
<script type="text/javascript">
//记录当前的拖拽元素
var dragElement = null;
//4个全局变量,用来记录当前拖拽元素以及鼠标的坐标
//由于不可能同时拖拽多个元素,所以不会冲突
var mouseY,mouseX,objY,objX;
//用于动态更新z-index,确保不会造成不该移动的元素瞎动。
var max = 1;
//初始化网页,遍历所有的元素,如果元素的class属性为"drag"
//则对其进行适当地设置
function dragInit(node){
if(node.className == "drag"){
node.onmousedown = down;
document.onmousemove = move;
node.onmouseover = over;
node.style.position = "relative";
node.dragging = false;
}
var children = node.childNodes;
for(var i = 0;i < children.length; i++){
dragInit(children[i]);
}
}
window.onload = function(){
//从document开始遍历
dragInit(document);
//确保在文档的任何位置将鼠标松开都将导致拖拽停止
document.onmouseup = docUp;
window.onblur = docUp;
}
//鼠标按下响应事件
function down(event)
{
event = event || window.event;
//按谁拽谁
dragElement = this;
//记录鼠标的当前坐标
mouseX = parseInt(event.clientX)
+(document.documentElement.scrollLeft || document.body.scrollLeft);
mouseY = parseInt(event.clientY)
+(document.documentElement.scrollTop || document.body.scrollTop);
//记录元素的当前坐标
objY = parseInt(getNodeStyle(dragElement,"top"));
objX = parseInt(getNodeStyle(dragElement,"left"));
//IE不返回未设置的CSS属性
if(!objY)objY=0;
if(!objX)objX=0;
this.style.zIndex = max++;
}
function move(event){
event = event || window.event;
if(dragElement){
var x,y;
//y等于鼠标当前y - 记录的鼠标y + 元素y ,后面的x一样
y = parseInt(event.clientY)
+(document.documentElement.scrollTop || document.body.scrollTop)
- mouseY + objY;
x = parseInt(event.clientX)
+(document.documentElement.scrollLeft || document.body.scrollLeft)
- mouseX + objX;
//更新元素的实际显示
dragElement.style.top = y + "px";
dragElement.style.left = x + "px";
//更新鼠标坐标和元素坐标的记录
objY=y;
objX=x;
mouseX = parseInt(event.clientX)
+(document.documentElement.scrollLeft || document.body.scrollLeft);
mouseY = parseInt(event.clientY)+(
document.documentElement.scrollTop || document.body.scrollTop);
}
}
function docUp(){
//停止拖拽
dragElement = null;
}
function over(){
this.style.cursor = "move";
}
//获得元素的坐标
function getNodeStyle(node,styleName){
var realStyle = null;
if(node.currentStyle){
realStyle = node.currentStyle[styleName];
}else if(window.getComputedStyle){
realStyle = window.getComputedStyle(node,null)[styleName];
}
return realStyle;
}
</script>
点击进入
测试页面。
JavaScript拖拽系列
1. JavaScript拖拽
2. JavaScript拖拽2——多元素、分离JS
3. JavaScript拖拽3——解决快速拖拽的问题
4. JavaScript拖拽4——获得元素的位置
5. JavaScript拖拽5——性能优化
6. JavaScript拖拽6——修复错误
分享到:
相关推荐
js JavaScript 拖放效果 将某元素拖拽入某个元素
javascript 拖放效果实现代码.docx
超经典JavaScript 拖放效果.拖放效果,也叫拖拽、拖动,学名Drag-and-drop.无可挑剔,超级经典,JavaScript 爱好者不下载,不去看一定后悔。欢迎下载.此信息出自:...
Javascript拖放框架.rar Javascript拖放框架.rar
( Sortable – 简单灵活的 JavaScript 拖放排序插件, ( Sortable – 简单灵活的 JavaScript 拖放排序插件 亲测很好用,修改简单
javascript高级技巧的应用——示例
绝对好用,可以看看小示例,一看就知道是不是自己想要的。
资源JavaScript 函数式编程精要 —— 签约作者安东尼知识分享
interact.js实现JavaScript拖放,调整大小和多点触摸惯性和捕捉手势
Javascript定时器(二)——setTimeout与setInterval 在 http://www.cnblogs.com/strick/p/3983904.html 有说明
HTML5中实现拖放效果无须借助javascript.docx
Dragula 是一个 JavaScript 库,实现了网页上的拖放功能。提供 JavaScript、AngularJS 和 React 版本。示例代码:dragula([left, right]).on('drag', function (el) { el.className = el.className.replace...
本文实例讲述了JavaScript实现的多种鼠标拖放效果。分享给大家供大家参考,具体如下: 这是一款JavaScript鼠标拖放效果代码,通过本示例了解触发对象,设置范围限制,指定容器大小水平及垂直锁定,还包括获取和释放...
拖放效果,也叫拖拽、拖动,学名Drag-and-drop ,是最常见的js特效之一。 如果忽略很多细节,实现起来很简单,但往往细节才是难点所在。
JavaScript擅长于修改页面中的DOM元素,但是我们使用JavaScript通常只是实现一些简单功能,例如实现图片的翻转,网页中的标签页,等等。这篇文章将向你展示如何在页面中,对创建的元素实现拖放。
全书配套269个JavaScript特效
用html5和javascript实现进程同步模拟——司机售票员问题。在文档后面还附有源代码。