您的位置:首页 > Web前端 > JavaScript

JavaScript特效:通过拖拽移动网页元素

2012-08-22 13:38 302 查看
本文由尤慕译自这里,转载请保留此条信息。


试着拖动下面任意一个Item:

Item 1 is <div>

Item 2 is <div>



NON-draggable element clicked


(上面的无效,你应该访问Here或原文)


介绍

关于用JavaScript实现拖拽,我没有找到一篇简洁又易懂的文章。因此我自己写了一篇,如下。


可拖动元素

首先把元素属性标记为
class="drag"
.
只需要 css 为:


.drag { position: relative; }


全局变量

要使代码可行,我们还需要一些全局变量:

var _startX = 0;            // 鼠标开始的位置
var _startY = 0;
var _offsetX = 0;           // 当前元素的位置
var _offsetY = 0;
var _dragElement;           // 需要从 OnMouseDown 传递给 OnMouseMove
var _oldZIndex = 0;         // 拖拽的时候增加z-index的值
var _debug = $('debug');    // 调试信息


JavaScript 事件

绑定到 document 上的相关事件:
onMouseDown
,
onMouseMove
,
and
onMouseUp
. 企图在元素上使用
onMouseMove
事件完成拖拽操作会产生问题,因为当鼠标移动过快时焦点容易跳出元素范围;除非鼠标重回到元素,
onMouseMove
事件将会停止触发。显然这不是我们想要的,所以我们把
onMouseMove
事件把绑定在document上。

首先初始化onmousedown和onmouseup这两个事件:

InitDragDrop();

function InitDragDrop()
{
document.onmousedown = OnMouseDown;
document.onmouseup = OnMouseUp;
}


再来看看
onMouseDown
:

function OnMouseDown(e)
{
// IE 有点弱智,不会传递event对象
if (e == null)
e = window.event;

// IE 使用 srcElement, 其它浏览器使用 target
var target = e.target != null ? e.target : e.srcElement;

_debug.innerHTML = target.className == 'drag'
? 'draggable element clicked'
: 'NON-draggable element clicked';

//  IE中left click == 1
// Firefox中left click == 0
if ((e.button == 1 && window.event != null ||
e.button == 0) &&
target.className == 'drag')
{
// 获取鼠标位置
_startX = e.clientX;
_startY = e.clientY;

// 获取元素位置
_offsetX = ExtractNumber(target.style.left);
_offsetY = ExtractNumber(target.style.top);

// 当拖拽时将元素放到前端
_oldZIndex = target.style.zIndex;
target.style.zIndex = 10000;

//  OnMouseMove中需要用到
_dragElement = target;

// 记元素跟着鼠标移动
document.onmousemove = OnMouseMove;

// 阻止鼠标移动过程中选中文本
document.body.focus();

// 阻止IE的文本选中
document.onselectstart = function () { return false; };
// 阻止IE的图像移动
target.ondragstart = function() { return false; };

// 阻止其它浏览器的文本选中
return false;
}
}


注释解释得很清楚,注意在拖动元素时文本被选中的情况。

一旦
OnMouseMove
绑定好, 它便会捕获鼠标移动事件:

function OnMouseMove(e)
{
if (e == null)
var e = window.event;

// 元素“拖动”的代码
_dragElement.style.left = (_offsetX + e.clientX - _startX) + 'px';
_dragElement.style.top = (_offsetY + e.clientY - _startY) + 'px';

_debug.innerHTML = '(' + _dragElement.style.left + ', ' +
_dragElement.style.top + ')';
}


鼠标释放后, 移除事件监听器 并且重置
_dragElement
:

function OnMouseUp(e)
{
if (_dragElement != null)
{
_dragElement.style.zIndex = _oldZIndex;

// 在下一次 OnMouseDown,重置这些变量
document.onmousemove = null;
document.onselectstart = null;
_dragElement.ondragstart = null;

// 通过它判断是否在进行拖动操作
_dragElement = null;

_debug.innerHTML = 'mouse up';
}
}


工具函数


function ExtractNumber(value)
{
var n = parseInt(value);

return n == null || isNaN(n) ? 0 : n;
}

// 简化获取元素的操作
function $(id)
{
return document.getElementById(id);
}


需要考虑的

本文只涉及到拖拽操作的表面,要深入请参考其它。


<iframe />

还没有测试在iframe下的情况,但很显然,应该用
event.screenX
event.screenY
代替
clientX
clientY
,如果你用的是
iframes
.


鼠标按钮

因为浏览器制造商爱搞不兼容,
event.button
的值也是随浏览器的不同而不同; 如下:
BrowserLeft ClickMiddle ClickRight Click
Firefox012
Internet Explorer142


浏览器兼容性

在 IE6&7, Firefox 3.0.5, Opera 9.2+, and Chrome 2.0测试通过。


支持一下

如果喜欢就转走吧. If you really want to show your appreciation... :-)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: