Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/html/78.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 使用拖放方式排列待办事项_Javascript_Html - Fatal编程技术网

Javascript 使用拖放方式排列待办事项

Javascript 使用拖放方式排列待办事项,javascript,html,Javascript,Html,我正在尝试创建一个待办事项列表,然后使用拖放来安排它。我有一个虚拟数据(列表项),我可以根据需要进行安排。我遇到的问题是,无法拖动或重新排列我添加到列表项中的任何新待办事项 下面是我的代码 var form=document.getElementById('addForm'); var itemList=document.getElementById('items'); 表.addEventListener(“提交”,addTodo); itemList.addEventListener('c

我正在尝试创建一个待办事项列表,然后使用拖放来安排它。我有一个虚拟数据(列表项),我可以根据需要进行安排。我遇到的问题是,无法拖动或重新排列我添加到列表项中的任何新待办事项

下面是我的代码

var form=document.getElementById('addForm');
var itemList=document.getElementById('items');
表.addEventListener(“提交”,addTodo);
itemList.addEventListener('click',removeItem)
函数addTodo(e){
e、 预防默认值()
//获取输入值
var newTodo=document.getElementById('todo');
//创造新的李元素
var li=document.createElement('li')
//添加类可拖动属性
li.className='draggable';
li.draggable=true
//使用输入值添加textnode
li.appendChild(document.createTextNode(newTodo.value))
//删除按钮
var delBtn=document.createElement('按钮')
delBtn.className='btn btn danger btn sm float right del';
delBtn.appendChild(document.createTextNode('X'))
李.儿童(delBtn)
itemList.appendChild(li)
newTodo.value=“”
}
函数删除项(e){
if(e.target.classList.contains('del')){
如果(确认('你确定吗?')){
var li=e.target.parentElement
itemList.removeChild(li)
}
}
}
const draggables=document.querySelectorAll('.draggable')
draggables.forEach(draggable=>{
DragTable.addEventListener('dragstart',()=>{
draggable.classList.add('draggable')
})
draggable.addEventListener('dragend',()=>{
draggable.classList.remove('draggable')
})
})
itemList.addEventListener('dragover',(e)=>{
e、 预防默认值()
const draggable=document.querySelector(“.draggable”)
常量afterElement=getDragAfterElement(可绘图,e.clientY)
控制台日志(后置元素);
if(afterElement==null){
itemList.appendChild(可拖动)
}否则{
itemList.insertBefore(可拖动,afterElement)
}
})
函数getDragAfterElement(DragTables,y){
const draggableElements=[…document.queryselectoral('.draggable:not(.draggable)]
log('draggable',draggableElements);
返回draggableElements.reduce((最近,子项)=>{
const box=child.getBoundingClientRect()
常数偏移=y-box.top-box.height/2
if(偏移量<0&&offset>最近的.offset){
返回{
抵销:抵销,
元素:child
}
}否则{
返回最近的
}
}, {
偏移量:数字负无穷大
}).元素
}

待办事项
加入到事情列表里
怎么办
任务名称
提交
待办事项清单
  • 第1项X
  • 第2项X 第3项X

如果我理解正确,您正在将一些事件附加到列表中的每个项目,以允许拖放功能

不过,新元素没有附加这些事件。您需要观察新元素,并为它们初始化拖放功能


注意:异端猴子链接到了一个更全面的链接。

您需要将此部分扭曲为函数

const draggables = document.querySelectorAll('.draggable')

        draggables.forEach(draggable => {
            draggable.addEventListener('dragstart', () => {
                draggable.classList.add('dragging')
            })
            draggable.addEventListener('dragend', () => {
                draggable.classList.remove('dragging')
            })
        })

并在
addTodo(e)
中调用称为事件绑定的函数

function addTodo(e) { 

  ....
  enableDragDrop();
}
另外,在pageload上调用函数show,默认情况下它应该绑定拖动事件

....
var form = document.getElementById('addForm');
var itemList = document.getElementById('items');

form.addEventListener('submit', addTodo);
itemList.addEventListener('click', removeItem)
enableDragDrop();
完成JS

    var form = document.getElementById('addForm');
    var itemList = document.getElementById('items');

    form.addEventListener('submit', addTodo);
    itemList.addEventListener('click', removeItem)
    enableDragDrop();

    function addTodo(e) {
        e.preventDefault()

        // get input value
        var newTodo = document.getElementById('todo');

        // create new li element
        var li = document.createElement('li')

        //add class draggable property
        li.className = 'draggable';
        li.draggable = true


        // add textnode with input value
        li.appendChild(document.createTextNode(newTodo.value))

        // delete button
        var delBtn = document.createElement('button')
        delBtn.className = 'btn btn-danger btn-sm float-right del';
        delBtn.appendChild(document.createTextNode('X'))
        li.appendChild(delBtn)

        itemList.appendChild(li)
        newTodo.value = "";

        enableDragDrop();
    }

    function removeItem(e) {
        if (e.target.classList.contains('del')) {
            if (confirm('Are you sure?')) {
                var li = e.target.parentElement
                itemList.removeChild(li)
            }
        }
    }

    function enableDragDrop() {
        const draggables = document.querySelectorAll('.draggable')

        draggables.forEach(draggable => {
            draggable.addEventListener('dragstart', () => {
                draggable.classList.add('dragging')
            })
            draggable.addEventListener('dragend', () => {
                draggable.classList.remove('dragging')
            })
        })
    }

    itemList.addEventListener('dragover', (e) => {
        e.preventDefault()
        const draggable = document.querySelector('.dragging')
        const afterElement = getDragAfterElement(draggable, e.clientY)

        console.log(afterElement);
        if (afterElement == null) {
            itemList.appendChild(draggable)
        } else {
            itemList.insertBefore(draggable, afterElement)
        }

    })

    function getDragAfterElement(draggables, y) {
        const draggableElements = [...document.querySelectorAll('.draggable:not(.dragging)')]
        console.log('Dragable', draggableElements);

        return draggableElements.reduce((closest, child) => {
            const box = child.getBoundingClientRect()
            const offset = y - box.top - box.height / 2

            if (offset < 0 && offset > closest.offset) {
                return {offset: offset, element: child}
            } else {
                return closest
            }
        }, {offset: Number.NEGATIVE_INFINITY}).element
    }
var form=document.getElementById('addForm');
var itemList=document.getElementById('items');
表.addEventListener(“提交”,addTodo);
itemList.addEventListener('click',removeItem)
enableDragDrop();
函数addTodo(e){
e、 预防默认值()
//获取输入值
var newTodo=document.getElementById('todo');
//创造新的李元素
var li=document.createElement('li')
//添加类可拖动属性
li.className='draggable';
li.draggable=true
//使用输入值添加textnode
li.appendChild(document.createTextNode(newTodo.value))
//删除按钮
var delBtn=document.createElement('按钮')
delBtn.className='btn btn danger btn sm float right del';
delBtn.appendChild(document.createTextNode('X'))
李.儿童(delBtn)
itemList.appendChild(li)
newTodo.value=“”;
enableDragDrop();
}
函数删除项(e){
if(e.target.classList.contains('del')){
如果(确认('你确定吗?')){
var li=e.target.parentElement
itemList.removeChild(li)
}
}
}
功能启用DragDrop(){
const draggables=document.querySelectorAll('.draggable')
draggables.forEach(draggable=>{
DragTable.addEventListener('dragstart',()=>{
draggable.classList.add('draggable')
})
draggable.addEventListener('dragend',()=>{
draggable.classList.remove('draggable')
})
})
}
itemList.addEventListener('dragover',(e)=>{
e、 预防默认值()
const draggable=document.querySelector(“.draggable”)
常量afterElement=getDragAfterElement(可绘图,e.clientY)
控制台日志(后置元素);
if(afterElement==null){
itemList.appendChild(可拖动)
}否则{
itemList.insertBefore(可拖动,afterElement)
}
})
函数getDragAfterElement(DragTables,y){
const draggableElements=[…document.queryselectoral('.draggable:not(.draggable)]
console.log('draggable',draggableEl
    var form = document.getElementById('addForm');
    var itemList = document.getElementById('items');

    form.addEventListener('submit', addTodo);
    itemList.addEventListener('click', removeItem)
    enableDragDrop();

    function addTodo(e) {
        e.preventDefault()

        // get input value
        var newTodo = document.getElementById('todo');

        // create new li element
        var li = document.createElement('li')

        //add class draggable property
        li.className = 'draggable';
        li.draggable = true


        // add textnode with input value
        li.appendChild(document.createTextNode(newTodo.value))

        // delete button
        var delBtn = document.createElement('button')
        delBtn.className = 'btn btn-danger btn-sm float-right del';
        delBtn.appendChild(document.createTextNode('X'))
        li.appendChild(delBtn)

        itemList.appendChild(li)
        newTodo.value = "";

        enableDragDrop();
    }

    function removeItem(e) {
        if (e.target.classList.contains('del')) {
            if (confirm('Are you sure?')) {
                var li = e.target.parentElement
                itemList.removeChild(li)
            }
        }
    }

    function enableDragDrop() {
        const draggables = document.querySelectorAll('.draggable')

        draggables.forEach(draggable => {
            draggable.addEventListener('dragstart', () => {
                draggable.classList.add('dragging')
            })
            draggable.addEventListener('dragend', () => {
                draggable.classList.remove('dragging')
            })
        })
    }

    itemList.addEventListener('dragover', (e) => {
        e.preventDefault()
        const draggable = document.querySelector('.dragging')
        const afterElement = getDragAfterElement(draggable, e.clientY)

        console.log(afterElement);
        if (afterElement == null) {
            itemList.appendChild(draggable)
        } else {
            itemList.insertBefore(draggable, afterElement)
        }

    })

    function getDragAfterElement(draggables, y) {
        const draggableElements = [...document.querySelectorAll('.draggable:not(.dragging)')]
        console.log('Dragable', draggableElements);

        return draggableElements.reduce((closest, child) => {
            const box = child.getBoundingClientRect()
            const offset = y - box.top - box.height / 2

            if (offset < 0 && offset > closest.offset) {
                return {offset: offset, element: child}
            } else {
                return closest
            }
        }, {offset: Number.NEGATIVE_INFINITY}).element
    }