fe-interview
fe-interview copied to clipboard
[js] 第164天 举例说明js如何拖拽排序?
第164天 举例说明js如何拖拽排序?
拆分功能,定义2个组件:
- dragArea 拖拽区组件,就是根据数组遍历生成列表项,做drag事件代理
- dragItem 单个列表成员渲染,绑定一些必要参数在dom上 每个item元素 打上h5 draggable 属性,并记下所在数组中的序号位置, 如 data-index = "0" 记下在dragArea的dragStart事件中元素序号A,dragEnd事件中的元素序号B 在数组里调整2个序号对应的对象的位置,更新渲染即可
- 可能和 @HCLQ 说的思路差不多
const $box = document.querySelector('.box');
let data = ['A', 'B', 'C', 'D'];
let fragment = document.createDocumentFragment();
let $li = document.createElement('li');
const render = () => {
while ($box.children.length > 0) {
$box.removeChild($box.firstChild)
}
data.forEach((e, i) => {
let $cloneLi = $li.cloneNode();
$cloneLi.innerHTML = e;
$cloneLi.setAttribute('draggable', true);
fragment.appendChild($cloneLi);
$box.appendChild(fragment);
});
}
const changeData = (fromValue, toValue) => {
// fromIndex 原数据索引
let fromIndex = data.indexOf(fromValue);
// 删除fromIndex
data.splice(fromIndex, 1);
// toIndex(注意在删除之后取)
let toIndex = data.indexOf(toValue);
// 在toIndex后插入源数据
data.splice(toIndex + 1, 0, fromValue);
}
render();
$box.setAttribute('draggable', false);
$box.addEventListener('dragstart', e => {
let $currentLi = e.target;
e.dataTransfer.setData('content', $currentLi.innerHTML);
})
$box.addEventListener('dragenter', e => { e.preventDefault(); })
$box.addEventListener('dragover', e => { e.preventDefault(); })
$box.addEventListener('drop', e => {
let fromValue = e.dataTransfer.getData('content');
let toValue = e.target.innerHTML;
changeData(fromValue, toValue)
render();
})
和楼上的实现方式差不多