`
zendj
  • 浏览: 121964 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
文章分类
社区版块
存档分类
最新评论

Web开发中的Drag&Drop完全手册

阅读更多

Web开发中的Drag&Drop完全手册


这几天做了一些drag&drop操作方面的工作,在这里把一些注意事项记录下来,算是给自己备个忘,也给需要做类似工作的人留个树阴。这里要讨论的drag&drop是指使用IE提供的内置机制,而不是使用鼠标模拟的那种"假"drag&drop,比如移动一个div或span 的效果那种。

要实现和控制drag&drop操作,那么首先第一点要弄清楚的是,到底哪些元素是可以在Web上被drag的?实际上IE默认给我们并让我们drag的元素并不多,它们是:图片、选中的文字(包括页面文字和文字控件(input, textarea)中的文字)和连接(普通连接和锚点)。除此之外,别的Web元素默认都不支持drag操作(在这些元素上面drag其实就是选择操作了),所以要实现对元素默认的drag&drop控制,只能选这3类元素来操作。

在BizStruct同学的斧正中提到,其实几乎所有的Html元素都是支持drag&drop的(见其回复),在此表示由衷的感谢。

接下来,那么哪些元素又是可以接受drop操作呢?任何页面上的可见元素都是可以接受drop操作的,而它们之间的不同只是在于默认的drop事件不一样。比如,文字控件(input, textarea)的默认drop事件就是获取drag操作传过来的文字内容;iframe元素的默认drop操作是到航道drag操作传过来的URL地址。当然绝大多数的Web元素的默认是操作是do nothing,什么也不做。

那么当进行drag&drop操作时,有那些是可控制和定制的内容呢?这里关于drag&drop提供了以下一些事件(我们把它们分为作用于来源对象和目的对象来分别讨论),先讨论主要作用于来源对象的事件:
·ondrag —— 在整个从drag动作开始,直道drop动作结束的过程中,都会触发的一个事件。
·ondragstart —— 在drag动作开始时,在来源对象上触发的一个事件。
·ondragend —— 在drop动作结束的时候,在来源对象上出发的一个事件。

而主要做要在目的对象上的事件:
·ondragenter —— 在drag动作进入某一有效目的元素时,在该目的元素上触发的一个事件。
·ondragover —— 在drag动作进入某一有效目的元素后,在该目的元素上触发的一个事件。
·ondragleave —— 在drag动作离开某一有效目的元素时,在该目的元素上触发的一个事件。
·ondrop —— 在任何有效目的元素上进行drop操作时,在该目的元素上触发的一个事件。

这里的来源和目的的划分不是绝对的,比如ondragover事件,在drag操作过程中,如果鼠标进入了来源对象中,同样的也会触发这个事件。这些事件触发的顺序是:来源对象 --> ondragstart --> ondrag --> ondragend;目的对象 --> ondragenter --> ondragover --> ( ondragleave | ondrap )。由于是分别在同一个对象上触发的事件,所以这个顺序很简单。那么对于一个完整的从来源对象到目的对象的drag&drop操作来说,事件的触发序列又是怎样呢?如果src表示来源对象,des表示目的对象,那么事件触发序列为:

src:ondragstart --> src:ondrag --> des:ondragenter --> des:ondragover --> ( des:ondragleave | des:ondrop ) --> src:ondragend.

示例为:Drag Source Drop Destination
// 如果alert窗口不响应鼠标点击可以使用键盘的space键来确定窗口

了解了事件触发顺序后,定制drag&drop过程中鼠标的光标形状也是非常重要的一个内容。因为用户的drag&drop的整个过程都需要靠鼠标光标的形状指导其进行操作,如果不能实时的调整光标为适合的型状,drag&drop操作对用户来说将无异于朦眼寻物。IE提供了用来控制的drag&drop过程中光标形状的两个属性,它们是:effectAllowed和dropEffect。

其属性分别为:
·effectAllowed: copy, link, move, copyLink, copyMove, all, none & uninitialized.
·dropEffect: copy, link, move, none.

前者effectAllowed是用来控制允许drag&drop操作类型的,所以这里的effect不是显示的"效果",而是是否可以执行的" 操作",并且该属性只能在ondragstart事件中进行初始化,之后再对其赋值将无效。当然如果只使用effectAllowed属性,就已经可以达到控制光标形状的作用了。只是effectAllowed属性在处理复合操作时,比如copyLink, copyMove和all,会默认显示靠前那个操作类型的鼠标类型。也就是说如果effectAllowed是copyMove,那么这是鼠标光标就是 copy形状。这下就知道为什么还要弄个dropEffect属性了吧?不过这个dropEffect属性中指定的effect,只能是之前 effectAllowed允许的操作类型范围中的值,否则没有效果(显示no-drop鼠标光标)。

示例为: Drag Source Drop Destination

如果查看代码,会发现在src和des的对象元素中,在ondragover事件里除了对dropEffect赋以适当的值外,还有两句话: event.returnValue=false;
event.cancelBubble=true;
只是由于页面元素在接受dragover的时候,本身都有其默认的鼠标光标显示型状,所以为了让用户自定义的鼠标光标生效,就需要使事件event的returenValue为false值并停止当事件的冒泡(event.cancelBubble=true)。

到目前为止,一个完整的drag&drop过程就差数据传递了,其实忙活了半天,这才是藏在所有交互操作和显示效果下面最重要的步骤。这个过程需要借助于IE提供的DHTML Data Transfer对象来完成,在window对象的属性event对象中,分别有两个Data Transfer对象各自的一个实例:一个叫dataTransfer,另一个叫clipboardData。这两个对象实例的行为非常相似,但又有一些区别,clipboardData顾名思义,它使用操作系统的剪贴板来存取数据,并有3个方法;而dataTransfer通过操作一个自己的内部剪贴板来存取数据(每次ondragend事件触发后就自动清空了),除了有和clipboardData相同的3个方法外,还有两个属性(就是前面介绍的那两个effectAllowed和dropEffect)。

我们这里不对clipboardData作更多的讨论,继续来看dataTransfer对象。它包含3个方法,它们是:setData (sDataFormat, sText), getData(sDataFormat)和clearData([sDataFormat])。它们更详细的使用和参数请参阅MSDN,这里我只用它们来实现drag&drop的数据传递。

示例为:Drag Source Drop Destination

其实很简单,就是在src的ondragstart中,调用event.dataTransfer.setData('TEXT', this.innerText),然后再des的ondrop事件中,调用this.innerText = event.dataTransfer.getData('TEXT')就行了。


posted on 2006-07-22 23:52 birdshome 阅读(2278) 评论(6) 编辑 收藏 引用 收藏至365Key 所属分类: Jscript&Dhtml开发


评论
# re: Web开发中的Drag&Drop完全手册 回复
可以去查一下 dragDrop 这个方法,有几十个元素支持,这些元素都支持 Drag&Drop,而不仅仅是你说的三种,否则微软没有必要提供这个方法。这些元素虽然都可以 Drag&Drop,但简单的应用只能拖拽文本,而高级的应用,比如拖拽控件,就需要一些技巧,这些网上都有很多应用。
另外你的第一个演示,如果拖拽 Drag Source 到 Drop Destination,再移出,会弹出 ondragleave 的 alert,这时这个 IE 窗口中 的鼠标就会被锁死,只有键盘能操作。 2006-07-23 11:00 | BizStruct # re: Web开发中的Drag&Drop完全手册 回复
@BizStruct 您好可以提供
Drag&Drop 的实例吗 2006-07-23 12:33 | 高海东 # re: Web开发中的Drag&Drop完全手册 回复
@BizStruct
非常感谢您的斧正,不过在正常模式的页面下,我确实无法drag&drop这三个以外的元素(除非使用controlRange来选中它们,但是这样即使选中也不能进行普通的drag&drop)。当然如果开启了block元素的contenteditable属性,确实可以 drag&drop容器中任意的元素,不过这些元素无法用过event.dataTransfer访问到,那么怎么使用呢?还望指教。

// 另外,网上搜Web上的drag&drop,出来的全都是mousemove那种东西。 2006-07-23 14:21 | birdshome
# re: Web开发中的Drag&Drop完全手册 回复
因为 dataTransfer 中只能保存文本,所以微软缺省只提供了你说的那三种元素的拖拽,其他元素的拖拽必须自己实现。
第一步是调用元素的 dragDrop(),应该在鼠标按下刚开始移动的时候。
第二步是响应 ondragstart 事件,设置 dataTransfer 中拖拽的文字。
后面的步骤就和系统缺省的拖拽一样了。
下面是一个可以拖拽标题的按钮。

<button onmousedown="event.srcElement.dragDrop();" ondragstart="event.dataTransfer.setData('Text', event.srcElement.value); event.dataTransfer.effectAllowed = 'CopyMove'; event.dataTransfer.dropEffect = 'move';">拖拽</button>

如果想拖拽元素,就要在 dataTransfer 中作文章,保存的文字是元素的id,在 drop 的时候,根据 id 找到被拖拽的元素,进行移动。
在我们的网站上的特性展示里有表格行拖拽的演示。

分享到:
评论

相关推荐

    深度VMware6.0完美精简汉化版+Drag&Drop_FixPatch

    最后,"Drag&Drop_FixPatch"是一个关键的修复补丁,专门解决了VMware Workstation中的拖放功能问题。在未应用此补丁前,用户可能无法直接在主机和虚拟机之间通过拖放操作传输文件,这是一个常见的用户痛点。应用这个...

    VMware6.0深度完美汉化版+vmtools+Drag&Drop_FixPatch(1)

    而且我已经把windows和linux的vmtools包,以及解决拖拽的问题脚本Drag&Drop_FixPatch一并加入进来,欢迎大家下载使用。 注意:因为大小问题,我分为两卷: VMware6.0深度完美汉化版+vmtools+Drag&Drop_FixPatch(1) ...

    Drag&Drop VCL for Delphi

    在实际开发过程中,使用Drag&Drop VCL时,需要注意以下几个关键步骤: 1. 初始化:在启动拖放操作前,需要确保组件已经正确初始化,通常是在OnMouseDown事件中启动拖动。 2. 数据格式:定义拖放的数据格式,如CF_...

    使用Drag&Drop接受文件名的输入框(13KB)

    "使用Drag&Drop接受文件名的输入框"是一种创新的交互方式,它允许用户通过简单的拖放操作来输入文件路径或文件名,提高了用户体验和工作效率。这种功能在多种应用中都非常实用,比如文件管理器、编辑器或者上传服务...

    HTML5实践Drag&Drop

    HTML5作为现代网页开发的标准,引入了许多新的特性和API,其中一项就是拖放(Drag&Drop)功能。这项技术允许用户通过鼠标或触控设备将元素从一个位置拖动到另一个位置,极大地提升了用户体验。本文将深入探讨HTML5中...

    VMware6.0深度完美汉化版+vmtools+Drag&Drop_FixPatch(2)

    而且我已经把windows和linux的vmtools包,以及解决拖拽的问题脚本Drag&Drop_FixPatch一并加入进来,欢迎大家下载使用。 注意:因为大小问题,我分为两卷: VMware6.0深度完美汉化版+vmtools+Drag&Drop_FixPatch(1) ...

    eclipse rcp drag&drop

    在Eclipse RCP应用中,Drag & Drop功能是提升用户体验的重要特性,让用户能够通过简单的鼠标操作移动或复制对象。 拖放(Drag & Drop)在Eclipse RCP中的实现涉及到多个组件和接口,主要包括以下几个关键知识点: ...

    一个很不错的drag & drop

    标题中的“一个很不错的drag & drop”指的是使用拖放(Drag & Drop)技术的一个应用程序或功能,这在网页设计和开发中非常常见。拖放功能允许用户通过鼠标将元素从一处拖到另一处,实现数据的移动、拷贝或者进行其他...

    WPF Drag&Drop

    综上所述,"WPF Drag&Drop"是WPF开发中的一个重要特性,它使得用户能够更加直观地操作界面元素,尤其适用于需要重新排序或移动数据的场景。通过熟练掌握这一技术,开发者可以构建出更符合用户习惯的现代应用程序。

    Blender插件-多格式文件拖拽导入插件 Drag & Drop Import V1

    Optimize your workflow with Drag and Drop Import for Blender. Quickly and easily import files by dragging them from your file explorer and dropping them into Blender’s 3D Viewport or Outliner. No ...

    Drag & drop source code android

    在Android开发中,拖放(Drag & Drop)功能是一种用户友好的交互方式,允许用户通过手势将一个元素从一处移动到另一处。本资源提供的"Drag & Drop source code android"包含了一个实现Android拖放功能的源代码示例,...

    Drag & Drop Modules

    在Web开发中,HTML5引入了`Drag and Drop` API,使得在浏览器中实现拖放操作变得更加简单和标准化。 在JavaScript虚拟机2(JSVM2)环境中,拖放功能的实现通常涉及到以下关键步骤: 1. **事件监听**:设置`...

    Window下拖放操作Drag & Drop 全解析

    Windows 操作系统中拖放操作(Drag & Drop)是一种常用的用户交互方式,允许用户在不同的程序窗口之间、同一个程序的不同窗口之间或同一程序同一窗口的不同控件之间进行移动、复制和粘贴等操作。拖放操作是在操作...

    Drag & Drop Files to Delete.zip

    在Web开发中,这种功能允许用户通过简单的拖放操作来处理文件,提高了用户体验。JavaScript作为前端开发的主要语言,提供了丰富的API来实现此类交互。 在JavaScript中,实现拖放功能主要依赖于HTML5的拖放API(Drag...

    Drag & Drop in Javascript.zip

    JavaScript中的拖放(Drag & Drop)功能是一种交互式技术,允许用户通过鼠标操作将元素从一个位置拖动到另一个位置,常用于文件管理、界面构建和游戏开发等场景。在这个"Drag & Drop in JavaScript"项目中,我们可能...

    Drag&drop.zip

    在我们的例子中,“Drag&drop.zip”项目包含了一个测试示例,展示了如何在两个列表框(QListWidget)之间进行拖放操作。 在Qt 5.6中,启用拖放功能通常需要以下步骤: 1. **启用拖放功能**:对于每个列表框,需要...

    WPF listbox之间拖动 drag&drop

    本教程将详细讲解如何在两个`ListBox`之间实现拖放(Drag & Drop)功能,以及如何添加上下按钮来控制`ListBox`内部元素的移动,并在拖动时改变边框颜色,提升用户体验。 首先,我们要了解`ListBox`的基本用法。`...

    【类库与框架】★★★★★-DragKit - an iOS framework for enabling drag & drop

    【类库与框架】★★★★★-DragKit - an iOS framework for enabling drag & drop【类库与框架】★★★★★-DragKit - an iOS framework for enabling drag & drop 1.适合学生学习研究参考 2.适合个人学习研究参考 3...

Global site tag (gtag.js) - Google Analytics