2、基于HTML5拖拽API的拖拽
前序知识介绍
一个典型的拖拽操做是这样的:用户用鼠标选中一个可拖动的(draggable)元素,移动鼠标到一个可放置的(droppable)元素,而后释放鼠标。 在操做期间,会触发一些事件类型,有一些事件类型可能会被屡次触发(好比drag 和 dragover 事件类型)。css
一个完整的drag and drop流程一般包含如下几个步骤:html
draggable="true"
实现元素的可拖拽.dragstart
设置拖拽数据copy
,move
,link
dragenter
或者dragover
取消浏览器默认行为使元素可拖放.drop
事件执行所需操做
这里涉及几个知识点:web
一、可拖动元素:又称为源对象,是指咱们鼠标点击以后准备拖动的对象(图片、div、文字等)
二、可放置元素:又称为目标对象,是指能够放置源对象的区域浏览器
三、事件:app
Event | On Event Handler | Description |
---|---|---|
drag | ondrag | 当拖动元素或选中的文本时触发 |
dragend | ondragend | 当拖拽操做结束时触发 (好比松开鼠标按键或敲“Esc”键) |
dragenter | ondragenter | 当拖动元素或选中的文本到一个可释放目标时触发 |
dragexit | ondragexit | 当元素变得再也不是拖动操做的选中目标时触发 |
dragleave | ondragleave | 当拖动元素或选中的文本离开一个可释放目标时触发 |
dragover | ondragover | 当元素或选中的文本被拖到一个可释放目标上时触发 |
dragstart | ondragstart | 当用户开始拖动一个元素或选中的文本时触发 |
drop | ondrop | 当元素或选中的文本在可释放目标上被释放时触发 |
ps:当从操做系统向浏览器中拖动文件时,不会触发dragstart 和dragend 事件ide
四、接口:函数
HTML5为全部的拖动相关事件提供了一个新的属性:this
属性和方法 |
描述 |
dropEffect | 拖拽交互类型,一般决定浏览器如何显示鼠标光标并控制拖放操做.常见的取值有copy ,move ,link 和none |
effectAllowed | 指定容许的交互类型,能够取值:copy ,move ,link ,copyLink ,copyMove ,limkMove , all , none 默认为uninitialized (容许全部操做) |
files | 包含File 对象的FileList 对象.从操做系统向浏览器拖放文件时有用. |
types | 保存DataTransfer 对象中设置的全部数据类型. |
setData(format, data) | 以键值对设置数据,format一般为数据格式,如text ,text/html |
getData(format) | 获取设置的对应格式数据,format与setData()中一致 |
clearData(format) | 清除指定格式的数据 |
setDragImage(imgElement, x, y) | 设置自定义图标 |
源对象和目标对象的事件间传递数据spa
event.dataTransfer {}//数据传递对象
源对象上的事件处理中保存数据:操作系统
event.dataTransfer.setData(key,value);//key,value必须都是字符串类型
如:
event.dataTransfer.setData("text/plain", "This is text to drag");
目标对象上的事件处理中读取数据:
var value2 = event.dataTransfer.getData(key);
demo
<div id="demo1"> <ul class="panel-list"> <li class="panel-item"></li> <li class="panel-item"></li> <li class="panel-item"></li> <li class="panel-item"></li> <li class="panel-item"></li> </ul> <h2>拖拽下面的方块到上面任意容器中</h2> <!-- 设置draggable使元素成为可拖拽元素 --> <div class="movable" id="demo1-src" draggable="true" draggable="true"> <img style="width:100%;" src="__ADMIN__/img/pbl/11.jpg"> </div> <style> #demo1 { margin: 20px; } #demo1 .panel-list { overflow: hidden; list-style: none; margin: 0; padding: 0; } #demo1 .panel-item { float: left; margin-right: 30px; width: 100px; height: 100px; background: #ddd; border: 1px solid #ddd; } #demo1-src { display: inline-block; width: 50px; height: 50px; background: purple; } #demo1 .over { border: 1px dashed #000; -webkit-transform: scale(0.8, 0.8); } </style> <script> (function () { var dnd = { // 初始化 init: function () { var me = this; me.src = document.querySelector('#demo1-src');//获取指定css选择器的元素 me.panelList = document.querySelector('.panel-list');//获取指定css选择器的元素 console.log( me.panelList ); //addEventListener('要监听的事件名','事件触发的函数',布尔:指定事件是否在捕获或冒泡阶段执行) // 为拖拽源监听dragstart,设置关联数据 me.src.addEventListener('dragstart', me.onDragStart, false); // 拖拽鼠标移入元素,在拖放目标上设置视觉反馈 me.panelList.addEventListener('dragenter', me.onDragEnter, false); // 取消元素dragover默认行为,使其可拖放 me.panelList.addEventListener('dragover', me.onDragOver, false); // 拖拽移出元素,清除视觉反馈 me.panelList.addEventListener('dragleave', me.onDragLeave, false); // 鼠标释放,在拖放目标上接收数据并处理 me.panelList.addEventListener('drop', me.onDrop, false); }, onDragStart: function (e) { //setData(format, data) 以键值对设置数据,format一般为数据格式,如text,text/html //设置可拖动元素的id(存起来) e.dataTransfer.setData('text/plain', 'demo1-src'); e.target.style.height="100px"; e.target.style.cursor="move"; }, //当拖动元素或选中的文本到一个可释放目标时触发 onDragEnter: function (e) { console.log(e.target); //e.target : <ul class="panel-list"></ul> //panel-list元素的子元素的类名列表中包含panel-item类则添加over类(呈现虚框效果) if (e.target.classList.contains('panel-item')) { //为panel-item的元素添加over类 e.target.classList.add('over'); } }, //当拖动元素或选中的文本离开一个可释放目标时触发(移除over类) onDragLeave: function (e) { e.target.style.cursor="move"; if (e.target.classList.contains('panel-item')) { e.target.classList.remove('over'); } }, //当元素或选中的文本被拖到一个可释放目标上时触发(取消事件的默认动做好比说表单自动提交) onDragOver: function (e) { e.preventDefault(); }, //当元素或选中的文本在可释放目标上被释放时触发 onDrop: function (e) { var id = e.dataTransfer.getData('text/plain'); var src = document.getElementById(id); var target = e.target; if (target.classList.contains('panel-item')) { target.appendChild(src); target.classList.remove('over'); } } }; dnd.init(); }()); </script> </div> <div id="demo2"> <h3>从文件夹中拖拽图片到下面的区域进行预览</h3> <ul class="preview"></ul> <style> #demo2 { margin: 20px; } #demo2 .preview { height: 300px; background: #ddd; } #demo2 li { float: left; margin-left: 40px; } #demo2 img { max-height: 150px; width: auto; } </style> <script> (function (w) { var doc = w.document; var dnd = { init: function () { var me = this; var preview = doc.querySelector('#demo2 .preview'); preview.addEventListener('dragover', function (e) { e.preventDefault(); }, false); preview.addEventListener('drop', function (e) { // 操做系统拖放文件到浏览器须要取消默认行为 e.preventDefault(); [].forEach.call(e.dataTransfer.files, function (file) { if (file && file.type.match('image.*')) { var reader = new FileReader(); reader.onload = function (e) { var img = doc.createElement('img'); img.src = e.target.result; var li = doc.createElement('li'); li.appendChild(img); preview.appendChild(li); }; reader.readAsDataURL(file); } }); }, false); } }; dnd.init(); }(window)); </script> </div> <!-- demo2 -->