拖动交换各元素位置,并以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);