拖放(drap && drop)在咱们平时的工做中,常常遇到。它表示:抓取对象之后拖放到另外一个位置。目前,它是HTML5标准的一部分。我从几个方面学习并实践这个功能。html
咱们先看下拖放的流程:chrome
选中 ---> 拖动 ---> 释放
而后,咱们一步步看下这个过程当中,会发生的事情。数组
在HTML5标准中,为了使元素可拖动,把draggable属性设置为true。
文本、图片和连接是默承认以拖放的,它们的draggable属性自动被设置成了true。
图片和连接按住鼠标左键选中,就能够拖放。
文本只有在被选中的状况下才能拖放。若是显示设置文本的draggable属性为true,按住鼠标左键也能够直接拖放。浏览器
draggable属性:设置元素是否可拖动。
语法:<element draggable="true | false | auto" >
app
每个可拖动的元素,在拖动过程当中,都会经历三个过程,拖动开始
-->拖动过程当中
--> 拖动结束
。学习
针对对象 | 事件名称 | 说明 |
---|---|---|
被拖动的元素 | dragstart | 在元素开始被拖动时候触发 |
drag | 在元素被拖动时反复触发 | |
dragend | 在拖动操做完成时触发 | |
目的地对象 | dragenter | 当被拖动元素进入目的地元素所占据的屏幕空间时触发 |
dragover | 当被拖动元素在目的地元素内时触发 | |
dragleave | 当被拖动元素没有放下就离开目的地元素时触发 |
dragenter和dragover事件的默认行为是拒绝接受任何被拖放的元素。所以,咱们必须阻止浏览器这种默认行为。e.preventDefault();flex
到达目的地以后,释放元素事件ui
针对对象 | 事件名称 | 说明 |
---|---|---|
目的地对象 | drop | 当被拖动元素在目的地元素里放下时触发,通常须要取消浏览器的默认行为。 |
<!DOCTYPE HTML> <html> <head> <title>拖放示例-文本</title> </head> <style> .src { display: flex; } .dropabled { flex: 1; } .txt { color: green; } .img { width: 100px; height: 100px; border: 1px solid gray; } .target { width: 200px; height: 200px; line-height: 200px; text-align: center; border: 1px solid gray; color: red; } </style> <body> <div class="src"> <div class="dragabled"> <div class="txt" id="txt"> 全部的文字均可拖拽。 <p draggable="true">此段文字设置了属性draggable="true"</p> </div> <div class="url" id="url"> <a href="http://weiqinl.com" target="_blank">我是url:http://weiqinl.com</a> </div> <img class="img" id="tupian1" src="img1.png" alt="图片1" /> <img class="img" id="tupian2" src="img2.png" alt="图片2" /> </div> <div id='target' class="dropabled target">Drop Here</div> </div> <script> var dragSrc = document.getElementById('txt') var target = document.getElementById('target') dragSrc.ondragstart = handle_start dragSrc.ondrag = handle_drag dragSrc.ondragend = handle_end function handle_start(e) { console.log('dragstart-在元素开始被拖动时候触发') } function handle_drag() { console.log('drag-在元素被拖动时候反复触发') } function handle_end() { console.log('dragend-在拖动操做完成时触发') } target.ondragenter = handle_enter target.ondragover = handle_over target.ondragleave = handle_leave target.ondrop = handle_drop function handle_enter(e) { console.log('handle_enter-当元素进入目的地时触发') // 阻止浏览器默认行为 e.preventDefault() } function handle_over(e) { console.log('handle_over-当元素在目的地时触发') // 阻止浏览器默认行为 e.preventDefault() } function handle_leave(e) { console.log('handle_leave-当元素离开目的地时触发') // 阻止浏览器默认行为 // e.preventDefault() } function handle_drop(e) { console.log('handle_drop-当元素在目的地放下时触发') var t = Date.now() target.innerHTML = '' target.append(t + '-拖放触发的事件。') e.preventDefault() } </script> </body> </html>
在整个拖放过程当中,咱们以上说的是表面现象,事件过程内部还会发生什么事情呢?请看下面👇的DataTransfer对象。code
与拖放操做所触发的事件同时派发的对象是DragEvent,它派生于MouseEvent,具备Event与MouseEvent对象的全部功能,并增长了dataTransfer属性。该属性用于保存拖放的数据和交互信息,返回DataTransfer对象。
// DataTransfer dataTransfer = DragEvent.dataTransfer
DataTransfer对象定义的属性和方法有不少种,咱们看下列入标准的几个。
属性 | 说明 |
---|---|
types | 只读属性。它返回一个咱们在dragstart事件中设置的拖动数据格式的数组。 格式顺序与拖动操做中包含的数据顺序相同。IE10+、Edge、safari3.一、Firefox3.5+ 和Chrome4以上支持该属性 |
files | 返回拖动操做中的文件列表。包含一个在数据传输上全部可用的本地文件列表。若是拖动操做不涉及拖动文件,此属性是一个空列表。 |
dropEffect | 获取当前选定的拖放操做的类型或将操做设置为新类型。它应该始终设置成effectAllowed的可能值之一【none、move、copy、link】。dragover事件处理程序中针对放置目标来设置dropEffect。 |
effectAllowed | 指定拖放操做所容许的效果。必须是其中之一【 none, copy, copyLink, copyMove, link, linkMove, move, all, uninitialized】默认为uninitialized 表示容许全部的效果。ondragstart处理程序中设置effectAllowed属性 |
方法 | 说明 |
---|---|
void setData(format, data) | 将拖动操做的拖动数据设置为指定的数据和类型。format能够是MIME类型 |
String getData(format) | 返回指定格式的数据,format与setData()中一致 |
void clearData([format]) | 删除给定类型的拖动操做的数据。若是给定类型的数据不存在,此方法不执行任何操做。若是不给定参数,则删除全部类型的数据。 |
void setDragImage(img, xOffset, yOffset) | 指定一副图像,当拖动发生时,显示在光标下方。大多数状况下不用设置,由于被拖动的节点被建立成默认图片。x,y参数分别指示图像的水平、垂直偏移量 |
//IE10及以前版本,不支持扩展的MIME类型名 //Firefox 5版本以前,不能正确的将url和text映射为text/uri-list 和text/plain var dataTransfer = event.dataTransfer; //读取文本, var text = dataTransfer.getData("Text"); //读取URL, var url = dataTransfer.getData("url") || dataTransfer.getData("text/uri-list");
说了这么多,若是浏览器不支持,也是白扯。
Method of easily dragging and dropping elements on a page, requiring minimal JavaScript.
要求最少的js,实现拖拽页面元素的简单方法
drag之浏览器支持程度--caniuse

note
dataTransfer.items
只有Chrome支持dropzone
属性,目前没有浏览器支持.setDragImage
任何类型的DOM元素。Chrome必须有HTMLImageElement
或者任何DOM元素,该DOM元素附加到DOM 和浏览器的.setDragImage
视口(viewport)内。dataTransfer.files
或者 .types
对象.setDragImage
dataTransfer.setData / getData
的有限支持格式如下,我在实际中遇到的状况,各浏览器对标准的实现仍是有差别的。
getData()
在chrome 62.0浏览器中,只能在drop
事件中生效。setDragImage
方法,指定的图像不存在,则拖动过程:
dragstart
和dragend
事件。dataTransfer.getData()
获得的内容。drop
事件中,添加: e.stopPropagation();// 再也不派发事件。解决Firefox浏览器,打开新窗口的问题
。draggable
属性设置为true
,才能够拖动。dropEffect
和 effectAllowed
。
effectAllowed
容许拖放操做的效果,最多不会超过那么几种。dropEffect
设置拖放操做的具体效果,只能是四种可能之一。effectAllowed
设置为none
,则不容许拖放元素。可是各个浏览器能触发的事件不同。(注意:safari能够拖放元素,并且会触发全部事件)dropEffect
设置为none
,则不容许被拖放到目的地元素中。effectAllowed
的值,那么若是要设置dropEffect
的值,其值必须和effectAllowed
的值一致,不然拖动效果无效,并且不容许将被拖放元素放到目的地元素中。(注:safari11.0.1有效果,并且也能拖动到目的地元素中,可是这不符合标准)。drag-drop-dataTransfer各属性方法示例
drag-drop事件触发
原生HTML5拖拽API,drag && drop 在实际工做中,仍是有不少状况下会遇到的。 以上,我只介绍了部分经常使用API。API不复杂,多看会儿,实践就知道了。各个浏览器,可能会在表现上,稍有不一样,但我相信你们仍是会向着标准发展的。