一个使用纯JavaScript实现的可拖动排序列表。用户可以通过鼠标拖动列表项来改变它们的顺序。
代码说明:
- HTML结构:
- 包含一个列表容器,其中包含多个可拖动的列表项。
- CSS样式:
- 设置了整体布局、颜色、间距等,使页面美观且易于阅读。
- 列表项设置了
cursor: move
以指示其可拖动。 - 拖动时添加了
dragging
类,使其透明度降低并稍微放大。 - 占位符用于指示拖动项将要插入的位置。
- JavaScript逻辑:
- 获取DOM元素并添加事件监听器。
- 定义了
dragstart
和dragend
事件处理程序,分别在开始和结束拖动时处理样式变化。 - 定义了
dragover
事件处理程序,用于确定拖动项将要插入的位置。 - 定义了
drop
事件处理程序,用于将拖动项插入到正确的位置。 getDragAfterElement
函数用于计算拖动项将要插入的具体位置。- 初始化了一个占位符元素,用于指示拖动项的目标位置。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>可拖动排序列表</title> <style> body { font-family: Arial, sans-serif; background-color: #f0f2f5; margin: 0; padding: 20px; display: flex; justify-content: center; align-items: center; height: 100vh; } .list-container { width: 300px; background-color: white; border-radius: 8px; box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); overflow: hidden; } .draggable-item { padding: 15px; border-bottom: 1px solid #ddd; cursor: move; transition: background-color 0.3s ease; } .draggable-item:last-child { border-bottom: none; } .draggable-item:hover { background-color: #f0f0f0; } .dragging { opacity: 0.5; transform: scale(1.05); z-index: 1000; } .placeholder { background-color: #f0f0f0; border: 1px dashed #ccc; min-height: 40px; box-sizing: border-box; } </style> </head> <body> <div class="list-container" id="list-container"> <div class="draggable-item" draggable="true">Item 1</div> <div class="draggable-item" draggable="true">Item 2</div> <div class="draggable-item" draggable="true">Item 3</div> <div class="draggable-item" draggable="true">Item 4</div> <div class="draggable-item" draggable="true">Item 5</div> </div> <script> const listContainer = document.getElementById('list-container'); let draggedItem = null; // 创建占位符 const createPlaceholder = () => { const placeholder = document.createElement('div'); placeholder.classList.add('placeholder'); return placeholder; }; // 开始拖动事件 listContainer.addEventListener('dragstart', (e) => { draggedItem = e.target; setTimeout(() => { draggedItem.classList.add('dragging'); }, 0); }); // 拖动结束事件 listContainer.addEventListener('dragend', () => { draggedItem.classList.remove('dragging'); draggedItem = null; }); // 允许放置事件 listContainer.addEventListener('dragover', (e) => { e.preventDefault(); const afterElement = getDragAfterElement(listContainer, e.clientY); const placeholder = document.querySelector('.placeholder') || createPlaceholder(); if (!afterElement) { listContainer.appendChild(placeholder); } else { listContainer.insertBefore(placeholder, afterElement); } }); // 放置事件 listContainer.addEventListener('drop', () => { const placeholder = document.querySelector('.placeholder'); listContainer.insertBefore(draggedItem, placeholder); placeholder.remove(); }); // 获取拖动后的位置 function getDragAfterElement(container, y) { const draggableItems = [...container.querySelectorAll('.draggable-item:not(.dragging)')]; return draggableItems.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; } </script> </body> </html>
One response
太棒了