最近在项目中遇到了拖动排序的需求,所以就学习了一下H5的新属性,写篇博客记录一下。
draggable属性是指定当前元素可以被拖动的属性;我们要为需要拖动的元素设置该属性
<div id="columns"> <div class="column" draggable="true"><header>A</header></div> <div class="column" draggable="true"><header>B</header></div> <div class="column" draggable="true"><header>C</header></div> </div>
<style>
/* Prevent the text contents of draggable elements from being selectable. */
[draggable] {
-moz-user-select: none;
-khtml-user-select: none;
-webkit-user-select: none;
user-select: none;
/* Required to make elements draggable in old WebKit */
-khtml-user-drag: element;
-webkit-user-drag: element;
}
.column {
height: 150px;
width: 150px;
float: left;
border: 2px solid #666666;
background-color: #ccc;
margin-right: 5px;
-webkit-border-radius: 10px;
-ms-border-radius: 10px;
-moz-border-radius: 10px;
border-radius: 10px;
-webkit-box-shadow: inset 0 0 3px #000;
-ms-box-shadow: inset 0 0 3px #000;
box-shadow: inset 0 0 3px #000;
text-align: center;
cursor: move;
}
.column header {
color: #fff;
text-shadow: #000 0 1px;
box-shadow: 5px;
padding: 5px;
background: -moz-linear-gradient(left center, rgb(0,0,0), rgb(79,79,79), rgb(21,21,21));
background: -webkit-gradient(linear, left top, right top,
color-stop(0, rgb(0,0,0)),
color-stop(0.50, rgb(79,79,79)),
color-stop(1, rgb(21,21,21)));
background: -webkit-linear-gradient(left center, rgb(0,0,0), rgb(79,79,79), rgb(21,21,21));
background: -ms-linear-gradient(left center, rgb(0,0,0), rgb(79,79,79), rgb(21,21,21));
border-bottom: 1px solid #ddd;
-webkit-border-top-left-radius: 10px;
-moz-border-radius-topleft: 10px;
-ms-border-radius-topleft: 10px;
border-top-left-radius: 10px;
-webkit-border-top-right-radius: 10px;
-ms-border-top-right-radius: 10px;
-moz-border-radius-topright: 10px;
border-top-right-radius: 10px;
}
.ghost{
optcity:0.6;
}
</style>
dragstart //当用户开始拖动一个元素或者一个选择文本的时候 dragstart 事件就会触发。drag //当元素或者选择的文本被拖动时触发 drag 事件 (每几百毫秒)dragenter //当拖动的元素或被选择的文本进入有效的放置目标时, dragenter 事件被触发。dragleave //当一个被拖动的元素或者被选择的文本离开一个有效的拖放目标时,将会触发dragleave 事件dragover //当元素或者选择的文本被拖拽到一个有效的放置目标上时,触发 dragover 事件(每几百毫秒触发一次)。drop //当一个元素或是选中的文字被拖拽释放到一个有效的释放目标位置时,drop 事件被抛出。dragend //拖放事件在拖放操作结束时触发(通过释放鼠标按钮或单击escape键)我们需要以下概念:源元素(拖动的起源点)、数据有效负载(我们尝试拖放的内容)和目标(接纳拖放内容的区域)。源元素可以是图片、列表、链接、文件对象、HTML 内容等。目标是接纳用户尝试放置的数据的放置区(或放置区组)。请注意,并非所有元素都可以作为目标(例如图片)。
dataTransfer是用于元素拖动时控制拖动的类型和数据交换的,主要有以下属性:
effectAllowed 的可能值之一;拖动时鼠标显示的效果,根据自己的功能来设定 可能的值:
方法:
obj.clearData(type);
DataTransfer 对象中没有数据,方法将返回一个空字符串。obj.getData(type);
obj.setData(type,data);
obj.setDragImage(imgElement,offsetX,offsetY); offsetX,offsetY为图片与鼠标的偏移量
function sortable(rootEl, onUpdate) {
var dragEl;
// 将所有的子类元素设置为可拖动的 draggable = true
[].slice.call(rootEl.children).forEach(function (itemEl) {
itemEl.draggable = true;
});
// 该函数负责进行排序
function _onDragOver(evt) {
evt.preventDefault();
evt.dataTransfer.dropEffect = 'move';
var target = evt.target;
if (target && target !== dragEl && target.nodeName == 'LI') {
// Sorting
rootEl.insertBefore(dragEl, target.nextSibling || target);
}
}
// 排序结束后的钩子函数
function _onDragEnd(evt){
evt.preventDefault();
dragEl.classList.remove('ghost');
rootEl.removeEventListener('dragover', _onDragOver, false);
rootEl.removeEventListener('dragend', _onDragEnd, false);
onUpdate(dragEl);
}
// 开始排序 监听父元素的dragstart 事件
rootEl.addEventListener('dragstart', function (evt){
// 保存当前被拖动的子元素
dragEl = evt.target;
// 设置移动的类型
evt.dataTransfer.effectAllowed = 'move';
// 设置要移动的数据
evt.dataTransfer.setData('Text', dragEl.textContent);
// 监听元素的dragover dragend 事件
rootEl.addEventListener('dragover', _onDragOver, false);
rootEl.addEventListener('dragend', _onDragEnd, false);
//这里如果不添加setTimeout拖出去的元素也会添加上该类名
setTimeout(function () {
dragEl.classList.add('ghost');
}, 0)
}, false);
}
// Using
sortable(document.getElementById('columns'), function (item) {
console.log(item);
});