fe-interview icon indicating copy to clipboard operation
fe-interview copied to clipboard

[js] 第164天 举例说明js如何拖拽排序?

Open haizhilin2013 opened this issue 5 years ago • 3 comments

第164天 举例说明js如何拖拽排序?

haizhilin2013 avatar Sep 26 '19 20:09 haizhilin2013

拆分功能,定义2个组件:

  1. dragArea 拖拽区组件,就是根据数组遍历生成列表项,做drag事件代理
  2. dragItem 单个列表成员渲染,绑定一些必要参数在dom上 每个item元素 打上h5 draggable 属性,并记下所在数组中的序号位置, 如 data-index = "0" 记下在dragArea的dragStart事件中元素序号A,dragEnd事件中的元素序号B 在数组里调整2个序号对应的对象的位置,更新渲染即可

HCLQ avatar Sep 27 '19 01:09 HCLQ

  • 可能和 @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();
})

vkboo avatar Sep 28 '19 08:09 vkboo

和楼上的实现方式差不多

xiaoqiangz avatar Jul 28 '22 08:07 xiaoqiangz