[翻译] 如何在 JavaScript 中实现拖放(下)

    译者: 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.如果拖动的元素不可见,我们将它放回它原来所在的地方。
None.gif//  iMouseDown represents the current mouse button state: up or down
ExpandedBlockStart.gifContractedBlock.gif
/**/ /**/ /**/ /*
InBlock.giflMouseState represents the previous mouse button state so that we can
InBlock.gifcheck for button clicks and button releases:
InBlock.gif
InBlock.gifif(iMouseDown && !lMouseState) // button just clicked!
InBlock.gifif(!iMouseDown && lMouseState) // button just released!
ExpandedBlockEnd.gif
*/

None.gif
var  mouseOffset  =   null ;
None.gif
var  iMouseDown   =   false
;
None.gif
var  lMouseState  =   false
;
None.gif
var  dragObject   =   null
;
None.gif
None.gif
//  Demo 0 variables

None.gif
var  DragDrops    =  [];
None.gif
var  curTarget    =   null
;
None.gif
var  lastTarget   =   null
;
None.gif
var  dragHelper   =   null
;
None.gif
var  tempDiv      =   null
;
None.gif
var  rootParent   =   null
;
None.gif
var  rootSibling  =   null
;
None.gif
ExpandedBlockStart.gifContractedBlock.gifNumber.prototype.NaN0
= function () dot.gif { return  isNaN( this ) ? 0 : this ;}

None.gif
ExpandedBlockStart.gifContractedBlock.gif
function  CreateDragContainer() dot.gif {
ExpandedSubBlockStart.gifContractedSubBlock.gif  
/**/ /**/ /**/
/*
InBlock.gif  Create a new "Container Instance" so that items from one "Set" can not
InBlock.gif  be dragged into items from another "Set"
ExpandedSubBlockEnd.gif  
*/

InBlock.gif  
var  cDrag  =  DragDrops.length;
InBlock.gif  DragDrops[cDrag] 
=
 [];
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif  
/**/ /**/ /**/
/*
InBlock.gif  Each item passed to this function should be a "container".  Store each
InBlock.gif  of these items in our current container
ExpandedSubBlockEnd.gif  
*/

ExpandedSubBlockStart.gifContractedSubBlock.gif  
for ( var  i = 0 ; i < arguments.length; i ++ ) dot.gif {
InBlock.gif    
var  cObj  =
 arguments[i];
InBlock.gif    DragDrops[cDrag].push(cObj);
InBlock.gif    cObj.setAttribute('DropObj', cDrag);
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif    
/**/ /**/ /**/
/*
InBlock.gif    Every top level item in these containers should be draggable.  Do this
InBlock.gif    by setting the DragObj attribute on each item and then later checking
InBlock.gif    this attribute in the mouseMove function
ExpandedSubBlockEnd.gif    
*/

ExpandedSubBlockStart.gifContractedSubBlock.gif    
for ( var  j = 0 ; j < cObj.childNodes.length; j ++ ) dot.gif {
InBlock.gif
InBlock.gif      
//  Firefox puts in lots of #text nodesskip these

InBlock.gif
       if (cObj.childNodes[j].nodeName == '#text')  continue ;
InBlock.gif
InBlock.gif      cObj.childNodes[j].setAttribute('DragObj', cDrag);
ExpandedSubBlockEnd.gif    }

ExpandedSubBlockEnd.gif  }

ExpandedBlockEnd.gif}

None.gif
ExpandedBlockStart.gifContractedBlock.gif
function  mouseMove(ev) dot.gif {
InBlock.gif    ev 
=  ev  ||
 window.event;
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif    
/**/ /**/ /**/
/*
InBlock.gif    We are setting target to whatever item the mouse is currently on
InBlock.gif    Firefox uses event.target here, MSIE uses event.srcElement
ExpandedSubBlockEnd.gif    
*/

InBlock.gif    
var  target  =  ev.target  ||  ev.srcElement;
InBlock.gif    
var  mousePos  =
 mouseCoords(ev);
InBlock.gif
InBlock.gif    
//  mouseOut event - fires if the item the mouse is on has changed

ExpandedSubBlockStart.gifContractedSubBlock.gif
     if (lastTarget  &&  (target !== lastTarget)) dot.gif {
InBlock.gif      
//  reset the classname for the target element

InBlock.gif
       var  origClass  =  lastTarget.getAttribute('origClass');
InBlock.gif      
if (origClass) lastTarget.className  =
 origClass;
ExpandedSubBlockEnd.gif    }

InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif    
/**/ /**/ /**/ /*
InBlock.gif    dragObj is the grouping our item is in (set from the createDragContainer function).
InBlock.gif    if the item is not in a grouping we ignore it since it can't be dragged with this
InBlock.gif    script.
ExpandedSubBlockEnd.gif    
*/

InBlock.gif    
var  dragObj  =  target.getAttribute('DragObj');
InBlock.gif
InBlock.gif    
//  if the mouse was moved over an element that is draggable

ExpandedSubBlockStart.gifContractedSubBlock.gif
     if (dragObj != null ) dot.gif {
InBlock.gif      
//  mouseOver event - Change the item's class if necessary

ExpandedSubBlockStart.gifContractedSubBlock.gif
       if (target != lastTarget) dot.gif {
InBlock.gif        
var  oClass  =
 target.getAttribute('overClass');
ExpandedSubBlockStart.gifContractedSubBlock.gif        
if (oClass) dot.gif
{
InBlock.gif          target.setAttribute('origClass', target.className);
InBlock.gif          target.className 
=
 oClass;
ExpandedSubBlockEnd.gif        }

ExpandedSubBlockEnd.gif      }

InBlock.gif
InBlock.gif      
//  if the user is just starting to drag the element
ExpandedSubBlockStart.gifContractedSubBlock.gif
       if (iMouseDown  &&   ! lMouseState) dot.gif {
InBlock.gif        
//  mouseDown target

InBlock.gif
        curTarget  =  target;
InBlock.gif
InBlock.gif        
//  Record the mouse x and y offset for the element

InBlock.gif
        rootParent  =  curTarget.parentNode;
InBlock.gif        rootSibling 
=
 curTarget.nextSibling;
InBlock.gif
InBlock.gif        mouseOffset   
=
 getMouseOffset(target, ev);
InBlock.gif
InBlock.gif        
//  We remove anything that is in our dragHelper DIV so we can put a new item in it.

InBlock.gif
         for ( var  i = 0 ; i < dragHelper.childNodes.length; i ++ ) dragHelper.removeChild(dragHelper.childNodes[i]);
InBlock.gif
InBlock.gif        
//  Make a copy of the current item and put it in our drag helper.

InBlock.gif
        dragHelper.appendChild(curTarget.cloneNode( true ));
InBlock.gif        dragHelper.style.display 
=
 'block';
InBlock.gif
InBlock.gif        
//  set the class on our helper DIV if necessary

InBlock.gif
         var  dragClass  =  curTarget.getAttribute('dragClass');
ExpandedSubBlockStart.gifContractedSubBlock.gif        
if (dragClass) dot.gif
{
InBlock.gif          dragHelper.firstChild.className 
=
 dragClass;
ExpandedSubBlockEnd.gif        }

InBlock.gif
InBlock.gif        
//  disable dragging from our helper DIV (it's already being dragged)
InBlock.gif
        dragHelper.firstChild.removeAttribute('DragObj');
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif        
/**/ /**/ /**/
/* </sp>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
ava实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),可运行高分资源 Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现
C语言是一种广泛使用的编程语言,它具有高效、灵活、可移植性强等特点,被广泛应用于操作系统、嵌入式系统、数据库、编译器等领域的开发。C语言的基本语法包括变量、数据类型、运算符、控制结构(如if语句、循环语句等)、函数、指针等。下面详细介绍C语言的基本概念和语法。 1. 变量和数据类型 在C语言,变量用于存储数据,数据类型用于定义变量的类型和范围。C语言支持多种数据类型,包括基本数据类型(如int、float、char等)和复合数据类型(如结构体、联合等)。 2. 运算符 C语言常用的运算符包括算术运算符(如+、、、/等)、关系运算符(如==、!=、、=、<、<=等)、逻辑运算符(如&&、||、!等)。此外,还有位运算符(如&、|、^等)和指针运算符(如、等)。 3. 控制结构 C语言常用的控制结构包括if语句、循环语句(如for、while等)和switch语句。通过这些控制结构,可以实现程序的分支、循环和多路选择等功能。 4. 函数 函数是C语言用于封装代码的单元,可以实现代码的复用和模块化。C语言定义函数使用关键字“void”或返回值类型(如int、float等),并通过“{”和“}”括起来的代码块来实现函数的功能。 5. 指针 指针是C语言用于存储变量地址的变量。通过指针,可以实现对内存的间接访问和修改。C语言定义指针使用星号()符号,指向数组、字符串和结构体等数据结构时,还需要注意数组名和字符串常量的特殊性质。 6. 数组和字符串 数组是C语言用于存储同类型数据的结构,可以通过索引访问和修改数组的元素。字符串是C语言用于存储文本数据的特殊类型,通常以字符串常量的形式出现,用双引号("...")括起来,末尾自动添加'\0'字符。 7. 结构体和联合 结构体和联合是C语言用于存储不同类型数据的复合数据类型。结构体由多个成员组成,每个成员可以是不同的数据类型;联合由多个变量组成,它们共用同一块内存空间。通过结构体和联合,可以实现数据的封装和抽象。 8. 文件操作 C语言通过文件操作函数(如fopen、fclose、fread、fwrite等)实现对文件的读写操作。文件操作函数通常返回文件指针,用于表示打开的文件。通过文件指针,可以进行文件的定位、读写等操作。 总之,C语言是一种功能强大、灵活高效的编程语言,广泛应用于各种领域。掌握C语言的基本语法和数据结构,可以为编程学习和实践打下坚实的基础。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值