译者:
Flyingis
终于完成了全文的翻译,由于时间比较参促,文章没有过多的校正与润色,阅读过程中难免会有些许生硬或不准确的感觉,请大家见量并指出,方便他人阅读。
原文作者将拖放功能的实现分步讲解,其核心的地方在于移动和放置元素时,鼠标、移动元素、目标元素关系的处理,只要这个问题处理好了,代码就很容易理解,译文仅供辅助参考之用。
整合所有的功能
最后我们使用所有代码片断,来创建一个完整的拖放函数脚本。我们所要做的第一件事情是DOM操作,如果你对此并不十分熟悉,可以阅读《 JavaScript Primer on DOM Manipulation 》。
接下来的代码创建容器和容器组,使得在这些容器中可以拖动每个元素,这在本文第二个demo的基础上来完成。这段代码能够用来重新规划元素的顺序,将导航窗口放在页面的左侧或右侧,或再加入你所能想到的其他的功能。
我们将使用伪代码来一步步进行讲解,将真实的代码通过注释的方式留给读者查看。
1.当文档第一次被加载时,我们创建一个名为dragHelper的DIV标签,当我们开始移动一个元素的时候,dragHelper将成为一个隐藏元素,可以四处移动。真实的元素并不会被拖动,仅仅使用insertBefore和appendChild来移动。我们在开始的时候隐藏dragHelper。
2.我们创建mouseDown和mouseUp函数。起初,所有的这些函数都假设记录了鼠标按钮的状态,以至于iMouseDown变量在鼠标按下的时候为true,没有按下的时候为false。
3.我们创建一个全局变量DragDrops,以及一个函数CreateDragContainer。DragDrops包含一组相互关联的容器。传入CreateDragContainer的任何变量(代表容器)被组织成一个新的集合,使元素能够在这些容器间自由移动。通过setAttribute,CreateDragContainer函数同样将各容器中的元素绑定在一起。
4.现在我们的代码知道每个元素所在的集合,现在来看mouseMove函数。mouseMove函数首先设置了一个变量target,表示鼠标下面的目标元素,如果这个元素在集合(用getAttribute判断)中就继续下面操作:
4.1.首先,在必要的时候,我们运行一个简单的脚本来改变目标元素的class属性,这样就创造了一个翻动的效果。
4.2.然后我们检查鼠标是否点击(因为我们的代码已经运行到这里),如果事件发生:
4.2.1.设置变量curTarget为当前元素。
4.2.2.记录元素当前在文档中的位置,以便在需要的时候可以将它的值取回。
4.2.3.将当前元素克隆到dragHelper,使得我们能够移动元素的隐藏备份。
4.2.4.因为在dragHelper中我们完全拥有了拖动元素的一个备份,这个元素会始终在鼠标下,我们必须移除dragObj属性,让代码知道dragObj已不在集合中。
4.2.5.我们快速记录集合中每个元素当前的位置、宽度和高度。当元素第一次开始被拖动时,我们仅需做一次这种工作,否则每当鼠标移动的时候我们都必须做一次,甚至一秒内几百次。
4.3.如果鼠标没有点击,要么我们和之前拥有同样的目标元素,要么没有目标元素,不论哪种情况我们都不会做任何事情。
5.现在我们检查curTarget变量。curTarget应该仅包含一个被拖动的对象,因此如果它存在,表示我们正在拖动一个元素:
5.1.移动隐藏DIV到鼠标,这个元素和文章前面所创建的元素一样能够被拖动。
5.2.然后我们检查鼠标是否存在于当前集合中每个容器中。
5.2.1.如果鼠标在某个容器中,我们检查容器中的每个元素,查看我们正拖动的元素属于哪个位置。
5.2.2.然后我们将所拖动的元素放置在容器中另一个元素的前面,或容器的最后位置。
5.2.3.最后我们确定元素可见。
6.剩下的事情就是捕获mouseUp事件:
6.1.首先需要隐藏dragHelper:它不再被需要,因为我们没有拖动任何东西。
6.2.如果拖动的元素是可见的,它已经存在于任何它所属的容器中,所有工作已完成。
6.3.如果拖动的元素不可见,我们将它放回它原来所在的地方。
// iMouseDown represents the current mouse button state: up or down

/**/ /**/ /**/
/*
lMouseState represents the previous mouse button state so that we can
check for button clicks and button releases:

if(iMouseDown && !lMouseState) // button just clicked!
if(!iMouseDown && lMouseState) // button just released!
*/
var mouseOffset = null
;
var iMouseDown = false
;
var lMouseState = false
;
var dragObject = null
;

// Demo 0 variables
var DragDrops =
[];
var curTarget = null
;
var lastTarget = null
;
var dragHelper = null
;
var tempDiv = null
;
var rootParent = null
;
var rootSibling = null
;


Number.prototype.NaN0 = function ()
{ return isNaN( this ) ? 0 : this ;}


function CreateDragContainer()
{

/**/ /**/ /**/ /*
Create a new "Container Instance" so that items from one "Set" can not
be dragged into items from another "Set"
*/
var cDrag = DragDrops.length;
DragDrops[cDrag] = [];


/**/ /**/ /**/ /*
Each item passed to this function should be a "container". Store each
of these items in our current container
*/

for ( var i = 0 ; i < arguments.length; i ++ )
{
var cObj = arguments[i];
DragDrops[cDrag].push(cObj);
cObj.setAttribute('DropObj', cDrag);


/**/ /**/ /**/ /*
Every top level item in these containers should be draggable. Do this
by setting the DragObj attribute on each item and then later checking
this attribute in the mouseMove function
*/

for ( var j = 0 ; j < cObj.childNodes.length; j ++ )
{

// Firefox puts in lots of #text nodesskip these
if (cObj.childNodes[j].nodeName == '#text') continue ;

cObj.childNodes[j].setAttribute('DragObj', cDrag);
}
}
}


function mouseMove(ev)
{
ev = ev || window.event;


/**/ /**/ /**/ /*
We are setting target to whatever item the mouse is currently on
Firefox uses event.target here, MSIE uses event.srcElement
*/
var target = ev.target || ev.srcElement;
var mousePos = mouseCoords(ev);

// mouseOut event - fires if the item the mouse is on has changed

if (lastTarget && (target !== lastTarget))
{
// reset the classname for the target element
var origClass = lastTarget.getAttribute('origClass');
if (origClass) lastTarget.className = origClass;
}


/**/ /**/ /**/ /*
dragObj is the grouping our item is in (set from the createDragContainer function).
if the item is not in a grouping we ignore it since it can't be dragged with this
script.
*/
var dragObj = target.getAttribute('DragObj');

// if the mouse was moved over an element that is draggable

if (dragObj != null )
{
// mouseOver event - Change the item's class if necessary

if (target != lastTarget)
{
var oClass = target.getAttribute('overClass');

if (oClass)
{
target.setAttribute('origClass', target.className);
target.className = oClass;
}
}

// if the user is just starting to drag the element

if (iMouseDown && ! lMouseState)
{
// mouseDown target
curTarget = target;

// Record the mouse x and y offset for the element
rootParent = curTarget.parentNode;
rootSibling = curTarget.nextSibling;

mouseOffset = getMouseOffset(target, ev);

// We remove anything that is in our dragHelper DIV so we can put a new item in it.
for ( var i = 0 ; i < dragHelper.childNodes.length; i ++ ) dragHelper.removeChild(dragHelper.childNodes[i]);

// Make a copy of the current item and put it in our drag helper.
dragHelper.appendChild(curTarget.cloneNode( true ));
dragHelper.style.display = 'block';

// set the class on our helper DIV if necessary
var dragClass = curTarget.getAttribute('dragClass');

if (dragClass)
{
dragHelper.firstChild.className = dragClass;
}

// disable dragging from our helper DIV (it's already being dragged)
dragHelper.firstChild.removeAttribute('DragObj');


/**/ /**/ /**/ /* </sp>
终于完成了全文的翻译,由于时间比较参促,文章没有过多的校正与润色,阅读过程中难免会有些许生硬或不准确的感觉,请大家见量并指出,方便他人阅读。
原文作者将拖放功能的实现分步讲解,其核心的地方在于移动和放置元素时,鼠标、移动元素、目标元素关系的处理,只要这个问题处理好了,代码就很容易理解,译文仅供辅助参考之用。
整合所有的功能
最后我们使用所有代码片断,来创建一个完整的拖放函数脚本。我们所要做的第一件事情是DOM操作,如果你对此并不十分熟悉,可以阅读《 JavaScript Primer on DOM Manipulation 》。
接下来的代码创建容器和容器组,使得在这些容器中可以拖动每个元素,这在本文第二个demo的基础上来完成。这段代码能够用来重新规划元素的顺序,将导航窗口放在页面的左侧或右侧,或再加入你所能想到的其他的功能。
我们将使用伪代码来一步步进行讲解,将真实的代码通过注释的方式留给读者查看。
1.当文档第一次被加载时,我们创建一个名为dragHelper的DIV标签,当我们开始移动一个元素的时候,dragHelper将成为一个隐藏元素,可以四处移动。真实的元素并不会被拖动,仅仅使用insertBefore和appendChild来移动。我们在开始的时候隐藏dragHelper。
2.我们创建mouseDown和mouseUp函数。起初,所有的这些函数都假设记录了鼠标按钮的状态,以至于iMouseDown变量在鼠标按下的时候为true,没有按下的时候为false。
3.我们创建一个全局变量DragDrops,以及一个函数CreateDragContainer。DragDrops包含一组相互关联的容器。传入CreateDragContainer的任何变量(代表容器)被组织成一个新的集合,使元素能够在这些容器间自由移动。通过setAttribute,CreateDragContainer函数同样将各容器中的元素绑定在一起。
4.现在我们的代码知道每个元素所在的集合,现在来看mouseMove函数。mouseMove函数首先设置了一个变量target,表示鼠标下面的目标元素,如果这个元素在集合(用getAttribute判断)中就继续下面操作:
4.1.首先,在必要的时候,我们运行一个简单的脚本来改变目标元素的class属性,这样就创造了一个翻动的效果。
4.2.然后我们检查鼠标是否点击(因为我们的代码已经运行到这里),如果事件发生:
4.2.1.设置变量curTarget为当前元素。
4.2.2.记录元素当前在文档中的位置,以便在需要的时候可以将它的值取回。
4.2.3.将当前元素克隆到dragHelper,使得我们能够移动元素的隐藏备份。
4.2.4.因为在dragHelper中我们完全拥有了拖动元素的一个备份,这个元素会始终在鼠标下,我们必须移除dragObj属性,让代码知道dragObj已不在集合中。
4.2.5.我们快速记录集合中每个元素当前的位置、宽度和高度。当元素第一次开始被拖动时,我们仅需做一次这种工作,否则每当鼠标移动的时候我们都必须做一次,甚至一秒内几百次。
4.3.如果鼠标没有点击,要么我们和之前拥有同样的目标元素,要么没有目标元素,不论哪种情况我们都不会做任何事情。
5.现在我们检查curTarget变量。curTarget应该仅包含一个被拖动的对象,因此如果它存在,表示我们正在拖动一个元素:
5.1.移动隐藏DIV到鼠标,这个元素和文章前面所创建的元素一样能够被拖动。
5.2.然后我们检查鼠标是否存在于当前集合中每个容器中。
5.2.1.如果鼠标在某个容器中,我们检查容器中的每个元素,查看我们正拖动的元素属于哪个位置。
5.2.2.然后我们将所拖动的元素放置在容器中另一个元素的前面,或容器的最后位置。
5.2.3.最后我们确定元素可见。
6.剩下的事情就是捕获mouseUp事件:
6.1.首先需要隐藏dragHelper:它不再被需要,因为我们没有拖动任何东西。
6.2.如果拖动的元素是可见的,它已经存在于任何它所属的容器中,所有工作已完成。
6.3.如果拖动的元素不可见,我们将它放回它原来所在的地方。



















































































































































