JavaScript 中的拖放重置问题

Issue with Drag-and-Drop Reset in JavaScript

提问人:lukas95 提问时间:8/30/2023 最后编辑:lukas95 更新时间:8/30/2023 访问量:47

问:

const grid = document.querySelector('.grid');
const leftDiv = document.querySelector('.left-side')
const rightDiv = document.querySelector('.right-side');
const btn = document.querySelector('.btn');
const resetBtn = document.querySelector('.js-reset-btn')

const pairs = [
    {pol: 'jeden', eng: 'one'},
     {pol: 'dwa', eng: 'two'},
     {pol: 'trzy', eng: 'three'},
     {pol: 'cztery', eng:'four'},
     {pol: 'piec', eng: 'five'},
    ]

    

    

const leftList = [];
const rightList = [];
let leftElement;


createList();

function createList() {
    leftDiv.innerHTML = '';
    rightDiv.innerHTML = '';

    const leftSide = [...pairs]
        .map(a => ({ value: a.pol, sort: Math.random() }))
        .sort((a, b) => a.sort - b.sort)
        .map(a => a.value)
        .forEach((item, index) => {

            leftElement = document.createElement('div');
            leftElement.setAttribute('data-index', index);
            leftElement.setAttribute('data-left', true);
            

            leftElement.innerHTML = `
                                    <div class="draggable left-draggable" draggable="true"  data-left="true">
                                        <p class="item-name">${item}</p>
                                    </div>
                                     `;
            leftDiv.appendChild(leftElement);

            leftList.push(leftElement)

        });

        const rightSide = [...pairs]
        .map(a => ({ value: a.eng, sort: Math.random() }))
    
        .sort((a, b) => a.sort - b.sort)
        .map(a => a.value)
        .forEach((item, index) => {

           const rightElement = document.createElement('div');
            rightElement.setAttribute('data-index', index);
            rightElement.setAttribute('data-right', true);
            

            rightElement.innerHTML = `
                                    <div class="draggable right-draggable" draggable="true" data-right="true">
                                        <p class="item-name">${item}</p>
                                    </div>
                                        `;

            rightDiv.appendChild(rightElement)

            rightList.push(rightElement)

        })

        addEventListener();
}





function addEventListener() {
    console.log('Adding event listeners...')
    document.querySelectorAll('.draggable').forEach((item, index) =>{
        item.addEventListener('dragstart', dragStart);
    });

    document.querySelectorAll('[data-index]').forEach(item => {
        item.addEventListener('dragenter', dragEnter);
        item.addEventListener('dragleave', dragLeave);
        item.addEventListener('dragover', dragOver);
        item.addEventListener('drop', dragDrop);
        
    })
    
}

let dragOrigin;
let dragStartIndex;

function dragStart(e) {
    

    if(e.target.getAttribute('data-left')){
        dragOrigin = 'left';
        dragStartIndex = +this.closest('[data-index]').getAttribute('data-index');
    
        
    } else if(e.target.getAttribute('data-right')){
        dragOrigin = 'right';
        dragStartIndex = +this.closest('[data-index]').getAttribute('data-index');
    
    }
     
}

function dragEnter() {
    
}
function dragLeave() {
   
}
function dragOver(e) {
    e.preventDefault();
   
}
function dragDrop(e) {   
    
    

    if(e.target.closest('[data-right]')){
       
        if(dragOrigin !== 'right'){
            return
        } else {
            const dragEndIndex = +this.closest('[data-index]').getAttribute('data-index');
            console.log(dragEndIndex);
            swapItems(dragStartIndex, dragEndIndex, 'right');
        }
        
    } else if(e.target.closest('[data-left]')){
        if(dragOrigin !== 'left'){
            return
        } else {
            const dragEndIndex = +this.closest('[data-index]').getAttribute('data-index');
            console.log(dragEndIndex);
            swapItems(dragStartIndex, dragEndIndex, 'left');
        }
        
    }

   
}


function swapItems(fromIndex, toIndex, data) {
    
   

    if(data === 'right' ){
        
        const itemOne = rightList[fromIndex].querySelector('.right-draggable');
        const itemTwo = rightList[toIndex].querySelector('.right-draggable');
            if(itemOne.getAttribute('data-right') && itemTwo.getAttribute('data-right')){
                rightList[fromIndex].appendChild(itemTwo)
                rightList[toIndex].appendChild(itemOne)
            } 
        
    } else if(data === 'left') {
    
        
        const itemOne = leftList[fromIndex].querySelector('.left-draggable');
        const itemTwo = leftList[toIndex].querySelector('.left-draggable');
            if(itemOne.getAttribute('data-left') && itemTwo.getAttribute('data-left')){
                leftList[fromIndex].appendChild(itemTwo)
                leftList[toIndex].appendChild(itemOne)
            }
        
    }
}

btn.addEventListener('click', checkOrder);



function checkOrder() {
    leftList.forEach((leftItem, index) => {
        const rightItem = rightList[index];

        let leftMatch = false;
        let rightMatch = false;

        pairs.forEach((pair, index) => {
            if(leftItem.querySelector('.left-draggable').textContent.trim() === pair.pol && rightItem.querySelector('.right-draggable').textContent.trim() === pair.eng){
                leftMatch = true;
                rightMatch = true;
            }
        })

        rightItem.classList.remove('right','wrong')
        leftItem.classList.remove('right','wrong')


        if(!leftMatch || !rightMatch){
            rightItem.classList.add('wrong')
            leftItem.classList.add('wrong')
        } else {
            rightItem.classList.add('right')
            leftItem.classList.add('right')
        }
    })
}

function resetApp() {
    // Clear dragged items
    leftList.forEach(leftItem => {
        const rightItem = rightList[leftItem.getAttribute('data-index')];

        // Reset position to the original container
        if (leftItem.getAttribute('data-left')) {
            leftDiv.appendChild(leftItem);
        } else if (rightItem.getAttribute('data-right')) {
            rightDiv.appendChild(rightItem);
        }
    });

    // Clear CSS classes indicating correct/incorrect matches
    leftList.forEach(leftItem => {
        const rightItem = rightList[leftItem.getAttribute('data-index')];
        leftItem.classList.remove('right', 'wrong');
        rightItem.classList.remove('right', 'wrong');
    });

    
// Remove existing event listeners
document.querySelectorAll('.draggable').forEach(item => {
    item.removeEventListener('dragstart', dragStart);
});

document.querySelectorAll('[data-index]').forEach(item => {
    item.removeEventListener('dragenter', dragEnter);
    item.removeEventListener('dragleave', dragLeave);
    item.removeEventListener('dragover', dragOver);
    item.removeEventListener('drop', dragDrop);
});
    // Regenerate and scramble the lists again
    createList();


}

resetBtn.addEventListener('click', resetApp );
*{
    box-sizing: border-box;
    margin: 0;
    padding: 0;
}

.grid {
    display: flex;
    margin: 50px auto;
    width: 500px;
    justify-content: center;
    /* gap: 30px; */
}

div[data-index] {
    padding: 25px;
    border: solid 2px #333;
    
}

.item-name {
    font-size: 25px;
    font-family: 'Lucida Sans', 'Lucida Sans Regular', 'Lucida Grande', 'Lucida Sans Unicode', Geneva, Verdana, sans-serif;
    text-transform: uppercase;
    padding: 10px 20px;
    border: 2px solid #ccc;
    border-radius: 16px;
    text-align: center;
    cursor: pointer;
    
}

.right{
    background-color: green;
}
.wrong{
    background-color: red;
}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <link rel="stylesheet" href="style.css">
</head>
<body>
    <div class="grid">
        <div class="left-side"></div>
        <div class="right-side"></div>
    </div>
    <button class="btn">Check Order</button>
    <button class="js-reset-btn">Reset</button>
    <script src="main.js"></script>
</body>
</html>

我正在使用 JavaScript 在 Web 应用程序中开发拖放功能。主要目标是允许用户匹配两个列表之间的项目,并使用重置按钮将项目恢复到随机位置。但是,我遇到了一个问题,即单击重置按钮后拖放功能中断。

重现步骤:

使用拖放功能加载页面。 将项目从一个列表拖到另一个列表。 单击“重置”按钮将项目恢复到随机位置。 尝试再次拖动项目并注意问题。

预期行为:

单击“重置”按钮后,我希望拖动的项目返回到随机位置,并且拖放功能可以像最初一样工作。

实际行为:

单击“重置”按钮后,拖动的项目会返回到随机位置,但拖放功能将停止工作。我无法拖动两个列表中的项目。

javascript html css 事件 拖放

评论


答: 暂无答案