拖动交换各元素位置,并以localStorage存储
#drag-and-drop { @include flexbox(row, wrap, space-between, flex-start); align-content: flex-start; list-style: none; padding: 0; margin: 0; .box { width: 32%; height: torem(150px); border: 1px solid color(black); margin-bottom: torem(15px); .item { @include flexbox(row, nowrap, center, center); width: 100%; height: 100%; color: color(blue); font-size: torem(16px); user-select: none; -webkit-user-drag: element; cursor: move; &:hover { text-decoration: none; } } } }
import { storage } from 'zp-lib'; const store = storage.proxy('dragAndDrop'); // 默认序列 const LIST = [ { id: 1, name: 'one', }, { id: 2, name: 'two', }, { id: 3, name: 'three', }, { id: 4, name: 'four', }, { id: 5, name: 'five', }, { id: 6, name: 'six', }, { id: 7, name: 'seven', }, { id: 8, name: 'eight', }, { id: 9, name: 'nine', }, ]; // drag & drop事件处理 const DragNDrop = { /** * 开始拖动 * @param {Object} e - 事件对象 * @param {Element} e.target - 被拖动的anchor元素 */ dragstart: (e) => { e.dataTransfer.effectAllowed = 'move'; e.dataTransfer.setData('from', e.target.dataset.id); }, /** * 拖动追踪 * @param {Object} e - 事件对象 */ dragover: (e) => { e.preventDefault(); e.dataTransfer.dropEffect = 'move'; }, /** * 释放拖动元素 * @param {Object} e - 事件对象 * @param {Element} e.target - 目标anchor元素 * @param {Element} e.currentTarget - 目标box元素 */ drop: (e) => { e.preventDefault(); const frag = document.createDocumentFragment(); const fromAnchor = document.querySelector(`.item--${e.dataTransfer.getData('from')}`); const fromBox = fromAnchor.parentElement; // move content frag.appendChild(fromAnchor); fromBox.appendChild(e.target); e.currentTarget.appendChild(frag); }, }; /** * 绑定事件 */ function attachEvents() { const { dragstart, dragover, drop, } = DragNDrop; Array.from(document.querySelectorAll('.box')).forEach((item) => { item.addEventListener('dragover', dragover, false); item.addEventListener('drop', drop, false); }); Array.from(document.querySelectorAll('.item')).forEach((item) => { item.onclick = (e) => { e.preventDefault(); }; item.addEventListener('dragstart', dragstart, false); }); } /** * 新建可移动元素 */ function buildItems() { const { data = LIST } = store; const frag = document.createDocumentFragment(); data.forEach(({ id, name }, index) => { const box = index + 1; const list = document.createElement('li'); const anchor = document.createElement('a'); const text = document.createTextNode(name); list.classList.add('box', `box--${box}`); anchor.classList.add('item', `item--${id}`); anchor.setAttribute('draggable', true); anchor.setAttribute('href', `#${name}`); anchor.dataset.id = id; anchor.dataset.name = name; anchor.appendChild(text); list.appendChild(anchor); frag.appendChild(list); }); const target = document.querySelector('#drag-and-drop'); target.innerHTML = ''; target.appendChild(frag); } document.addEventListener('DOMContentLoaded', () => { buildItems(); attachEvents(); }, false); window.addEventListener('beforeunload', () => { const arr = Array.from(document.querySelectorAll('.item')).map((elem) => { const { id, name } = elem.dataset; return { id, name, }; }); store.data = arr; }, false);