HTML5拖放換位
線上示例:示例
github:連結
頁面結構
<ul class="drop-div">
<li href="/black">
<div>1</div>
<p>1</p>
</li>
<li href="/green">
<div>2</div>
<p>2</p>
</li>
<li href="/red">
<div>3</div>
<p>3</p>
</li>
<li href="/red">
<div>4</div>
<p>4</p>
</li>
<li href="/red">
<div>5</div>
<p>5</p>
</li>
</ul>
源碼
;(function (global, fn, plugin) {
global[plugin] = fn.call(plugin);
})(window, function () {
var _callback,
_isContinue,
_CORE = {
bindDrop: function(elem) {
var list = [].slice.call(document.querySelectorAll(elem));
list.forEach(function (l, index) {
l.setAttribute('draggable', true);
// 如果沒有加入唯一ID,就
if (l.id === '' || l.id === null) {
l.id = 'udrop-' + index;
}
l.addEventListener('dragstart', _CORE.drag); // 拖拽開始
l.addEventListener('dragover', _CORE.dropOver); // 拖動
l.addEventListener('drop', _CORE.drop); // 放入
l.parentNode.addEventListener('dragover', _CORE.dropOver); // 拖動到父級
});
},
drag: function(e) {
e.dataTransfer.setData("Text", e.target.id);
},
drop: function(e) {
e.preventDefault();
e.stopPropagation();
var l = e.dataTransfer.getData('Text');
var dragElem = document.getElementById(l); // 拖動的元素
var dropElem = e.target; // 拖入的元素
var parentElem = dropElem.parentNode; // 父元素
var dragIndex; // 擷取拖動的元素下标
var bool = true;
// 判斷是否有相同的父級元素
while (bool) {
if (parentElem.isEqualNode(dragElem.parentNode)) {
dragIndex = _CORE.getIndex(parentElem, dropElem);
bool = false;
} else {
dropElem = parentElem;
parentElem = parentElem.parentNode;
}
if (dragElem.parentNode === null) {
bool = false;
console.error('ERROR: 拖動元素的DOM結構好像有點問題哦');
}
}
var dropElemIndex = _CORE.getIndex(parentElem, dragElem); // 擷取拖動元素下标
// callback回調
_callback(dragElem, dropElem, dragIndex, dropElemIndex);
if (!_isContinue) {
return false;
}
// 如果是從後往前改變位置
if (dropElemIndex > dragIndex) {
parentElem.insertBefore(dropElem, parentElem.childNodes[dropElemIndex]);
parentElem.insertBefore(dragElem, parentElem.childNodes[dragIndex]);
} else {
parentElem.insertBefore(dragElem, parentElem.childNodes[dragIndex]);
parentElem.insertBefore(dropElem, parentElem.childNodes[dropElemIndex]);
}
},
dropOver: function (e) {
e.preventDefault();
e.stopPropagation();
},
// 擷取相對于父級元素的位置
getIndex: function (parent, child) {
var index;
for (var x = 0; x < parent.childNodes.length; x++) {
if (parent.childNodes[x].id === child.id) {
index = x;
break;
}
}
return index;
}
};
return {
init: function (elem, callback, isContinue) {
_callback = callback;
_isContinue = isContinue === undefined ? true : isContinue;
_CORE.bindDrop(elem);
}
};
}, 'uChangePosition');
調用
uChangePosition.init('.drop-div li', function (dragElem, dropToElem, dragIndex, dropElemIndex) {
console.log(dragElem, dropToElem, dragIndex, dropElemIndex);
}, true);