天天看點

HTML5拖放換位

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);