以前实现元素的拖拽需要使用javascript大段代码实现,又是记录初始位置,又是记录位移等等很麻烦,现在HTML5
提供了专门的拖拽与拖放的API
,先说说相关API
事件 | 产生的源对象 | 说明 |
---|---|---|
drag | 被拖动的元素 | 这个事件在拖拽源触发。即在拖拽操作中触发dragstart 事件的元素。 |
drop | 拖放的目标元素 | 这个事件在拖拽操作结束释放时于释放元素上触发。一个监听器用来响应接收被拖拽的数据并插入到释放之地。这个事件只有在需要时才触发。当用户取消了拖拽操作时将不触发,例如按下了Escape(ESC) 按键,或鼠标在非可释放目标上释放了按键。 |
dragstart | 被拖动的元素 | 当一个元素开始被拖拽的时候触发。用户拖拽的元素需要附加dragstart 事件。在这个事件中,监听器将设置与这次拖拽相关的信息,例如拖动的数据和图像。 |
dragenter | 拖动过程中鼠标经过的元素 | 当拖拽中的鼠标第一次进入一个元素的时候触发。这个事件的监听器需要指明是否允许在这个区域释放鼠标。如果没有设置监听器,或者监听器没有进行操作,则默认不允许释放。当你想要通过类似高亮或插入标记等方式来告知用户此处可以释放,你将需要监听这个事件。 |
dragleave | 拖动过程中鼠标经过的元素 | 当拖拽中的鼠标离开元素时触发。监听器需要将作为可释放反馈的高亮或插入标记去除。 |
dragend | 拖动的对象元素 | 拖拽源在拖拽操作结束将得到dragend 事件对象,不管操作成功与否。 |
dragover | 拖动过程中鼠标经过的元素 | 当拖拽中的鼠标移动经过一个元素的时候触发。大多数时候,监听过程发生的操作与dragenter 事件是一样的。 |
兼容如下
其他设置
1、
DataTransfer
对象:
退拽对象用来传递的媒介,使用一般为Event.dataTransfer
。2、
draggable
属性:
就是标签元素要设置draggable=true
,否则不会有效果,例如:
1 <div title="拖拽我" draggable="true">列表1</div>3、
Event.preventDefault()
方法:
阻止默认的些事件方法等执行。在dragover
中一定要执行preventDefault()
,否则drop
事件不会被触发。另外,如果是从其他应用软件或是文件中拖东西进来,尤其是图片的时候,默认的动作是显示这个图片或是相关信息,并不是真的执行drop
。此时需要用用document
的dragover
事件把它直接干掉。
上面有一个很关键的对象DataTransfer
,在进行拖放操作时,DataTransfer
对象用来保存被拖动的数据。它可以保存一项或多项数据、一种或者多种数据类型,其属性和方法如下
属性/方法 | 类型/参数 | 作用 |
---|---|---|
dropEffect | String | 设置实际的放置效果,它应该始终设置成 effectAllowed 的可能值之一 ,可以指定为none (禁止所有操作)、copy (复制到新的位置)、link (建立一个源位置到新位置的链接)、move (移动到新的位置 ) |
effectAllowed | String | 用来指定拖动时被允许的效果,可以指定为 copy (复制到新的位置), move (移动到新的位置 ), link (建立一个源位置到新位置的链接), copyLink (允许复制或者链接), copyMove (允许复制或者移动), linkMove ( 允许链接或者移动), all (允许所有的操作), none (禁止所有操作), uninitialized (缺省值(默认值), 相当于 all . ) |
files | FileList | 包含一个在数据传输上所有可用的本地文件列表。如果拖动操作不涉及拖动文件,此属性是一个空列表。此属性访问指定的FileList 中无效的索引将返回未定义(undefined) 。 |
types | DOMStringList | 保存一个被存储数据的类型列表作为第一项,顺序与被添加数据的顺序一致。如果没有添加数据将返回一个空列表。 |
addElement() | element(要添加的元素) | 设置拖动源。通常你不需要改变这项,如果修改这项将会影响拖动的哪个节点和dragend 事件的触发。默认目标是被拖动的节点。 |
clearData() | type(要删除的数据类型) | 删除与给定类型关联的数据。类型参数是可选的。如果类型为空或未指定,将删除所有类型相关联的数据。如果不存在指定类型的数据,或数据传输不包含任何数据,此方法将没有任何效果。 |
getData() | type(要检索的数据类型) | 检索(取得)给定类型的数据,如果给定类型的数据不存在或者数据转存(data transfer) 没有包涵数据,方法将返回一个空字符串。 |
setData() | type(要添加的数据类型), data(要添加的数据) | 为一个给定的类型设置数据。如果该数据类型不存在,它将添加到的末尾,这样类型列表中的最后一个项目将是新的格式。如果已经存在的数据类型,替换相同的位置的现有数据。就是,当更换相同类型的数据时,不会更改类型列表的顺序。 |
setDragImage() | image (要用作拖动反馈图像元素), x (图像内的水平偏移量), y (图像内的垂直偏移量) |
自定义一个期望的拖动时的图片。大多数情况下,这项不用设置,因为被拖动的节点被创建成默认图片。坐标指定图像相对于鼠标光标位置的偏移量。 |
说了这么多相关的API,现在就开始实际操作一下
功能检测
在使用darg之前,我们需要判断是否支持,这里可以使用一个工具modernizr,使用方法如下
创建可拖动内容
在要设为可移动的元素上设置 draggable=true 属性。可以是任何能启用拖动功能的内容,包括图片、链接、文件或其他 DOM 节点,实例如下:
See the Pen BNJBQB
完成拖动
- 在您的内容上定义 draggable=”true” 属性后,附加 dragstart 事件处理程序以展开每一列的 DnD 序列。
- 每种事件类型的 this/e.target 各不相同,具体取决于我们在 DnD 事件模型中所处的位置。
- 如果要拖动链接之类的内容,我们需要阻止浏览器的默认行为,不让其导航至该链接。为实现这一目标,可调用 dragover 事件中的 e.preventDefault()。在同一处理程序中调用 return false 也是个不错的做法。浏览器与这些所需操作会有点不协调,但并不会有所损害。
- 我们使用 dragenter 触发“over”类,而不是使用 dragover。如果我们使用 dragover,系统将反复触发 CSS 类,因为 dragover 事件会在鼠标悬停在列上方时不断启动。这将最终导致浏览器的渲染器进行大量不必要的工作。
- dataTransfer 可在 dragstart 事件中进行设置,并在 drop 事件中读取/处理。调用 e.dataTransfer.setData(format, data) 会将对象内容设置成 MIME 类型,并将数据有效负载作为参数传递。
See the Pen qdpWrK
购物车
See the Pen WvzPjm
实现了购物车的添加并计算价格的功能,这里还有个功能以后完善,就是删除购物车商品的功能,后期完善。
参考资料:
本机 HTML5 拖放