用html
+jq
实现元素的拖动效果
效果图如下:
将【item10】拖动到【item1】前面
直接上代码:
html部分
<ul id="sortableList"><li id="item1" class="w1" draggable="true">Item 1</li><li id="item2" class="w2" draggable="true">Item 2</li><li id="item3" class="w3" draggable="true">Item 3</li><li id="item4" class="w1" draggable="true">Item 4</li><li id="item5" class="w1" draggable="true">Item 5</li><li id="item6" class="w2" draggable="true">Item 6</li><li id="item7" class="w3" draggable="true">Item 7</li><li id="item8" class="w1" draggable="true">Item 8</li><li id="item9" class="w2" draggable="true">Item 9</li><li id="item10" class="w3" draggable="true">Item 10</li>
</ul>
js部分
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script><script>document.addEventListener('DOMContentLoaded', function () {const sortableList = document.getElementById('sortableList');const items = sortableList.querySelectorAll('li');items.forEach((item) => {item.addEventListener('dragstart', dragStart);item.addEventListener('dragover', dragOver);item.addEventListener('drop', drop);item.addEventListener('dragenter', dragEnter);item.addEventListener('dragleave', dragLeave);});function dragStart(e) {e.dataTransfer.setData('text/plain', e.target.id);// setTimeout(() => {// e.target.classList.add('hide');// }, 0);console.log('Drag started:', e.target.id);}function dragOver(e) {e.preventDefault();e.target.classList.add('over');console.log('Drag over:', e.target.id);}function dragEnter(e) {e.preventDefault();console.log('Drag enter:', e.target.id);}function dragLeave(e) {e.target.classList.remove('over');console.log('Drag leave:', e.target.id);}function drop(e) {e.preventDefault();const draggedItemId = e.dataTransfer.getData('text/plain');const draggedItem = document.getElementById(draggedItemId);const targetItem = e.target;if (targetItem !== draggedItem) {const targetIndex = Array.from(items).indexOf(targetItem);const draggedIndex = Array.from(items).indexOf(draggedItem);if (targetIndex > draggedIndex) {targetItem.parentNode.insertBefore(draggedItem,targetItem.nextSibling);} else {targetItem.parentNode.insertBefore(draggedItem, targetItem);}}e.target.classList.remove('over');draggedItem.classList.remove('hide');console.log('Drop:', e.target.id);console.log('在这里加检查宽度方法');checkWidth();}});// 检查宽度function checkWidth(first = true) {//清空空白块if (first) $('#sortableList li.box').remove();//盒子宽度let boxWidth = document.getElementById('sortableList').offsetWidth;//当前li行的宽度let rowLiWidth = 0;//循环lifor (let i = 0; i < $('#sortableList li').length; i++) {var outerWidthWithMargin = $('#sortableList li').eq(i).outerWidth(true);var itemWidth = parseFloat(outerWidthWithMargin.toFixed(2));console.log(i, rowLiWidth, itemWidth);//当前li行的宽度+当前项宽度let RAW = rowLiWidth + itemWidth;//如果当前li行的宽度+当前项宽度大于盒子宽度,则添加空白块,并重新计算。//3是容错宽度。if (RAW >= boxWidth ||(RAW - boxWidth >= -3 && RAW - boxWidth <= 3)) {//宽度大于盒子宽度,则添加空白块,并重新计算。if (RAW > boxWidth) {let thisWidth = boxWidth - rowLiWidth;if (thisWidth > 3) {$('#sortableList li').eq(i).before(`<li class="box" style="width:${thisWidth}px"></li>`);rowLiWidth = 0; //重新计算。checkWidth(false);break;}}rowLiWidth = 0; //重新计算。} else {rowLiWidth += itemWidth;}if (i == $('#sortableList li').length - 1) {let thisWidth = boxWidth - rowLiWidth;$('#sortableList li').eq(i).after(`<li class="box" style="width:${thisWidth}px"></li>`);break;}}}</script>
css部分
<style>* {box-sizing: border-box;}#sortableList {list-style-type: none;padding: 0;display: flex;flex-wrap: wrap;position: relative;}#sortableList:after {border-top: none;border-left: none;position: absolute;top: 0;left: 0;width: 100%;height: 100%;z-index: 0;pointer-events: none;}#sortableList:after,#sortableList li:after {content: '';border: 1px solid #eee;position: absolute;top: 0;left: 0;width: 100%;height: 100%;z-index: 0;pointer-events: none;}#sortableList li:after {border-right: none;border-bottom: none;}#sortableList li {padding: 8px;background-color: #fff;cursor: move;position: relative;}#sortableList li.box {background-color: #fff;}#sortableList li.over {border: 2px dashed #000;}#sortableList li.w1 {width: 20%;}#sortableList li.w2 {width: 30%;}#sortableList li.w3 {width: 50%;}#sortableList li.hide {display: none;}</style>
完整版代码如下:
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8" /><title>Title</title><style>* {box-sizing: border-box;}#sortableList {list-style-type: none;padding: 0;display: flex;flex-wrap: wrap;position: relative;}#sortableList:after {border-top: none;border-left: none;position: absolute;top: 0;left: 0;width: 100%;height: 100%;z-index: 0;pointer-events: none;}#sortableList:after,#sortableList li:after {content: '';border: 1px solid #eee;position: absolute;top: 0;left: 0;width: 100%;height: 100%;z-index: 0;pointer-events: none;}#sortableList li:after {border-right: none;border-bottom: none;}#sortableList li {padding: 8px;background-color: #fff;cursor: move;position: relative;}#sortableList li.box {background-color: #fff;}#sortableList li.over {border: 2px dashed #000;}#sortableList li.w1 {width: 20%;}#sortableList li.w2 {width: 30%;}#sortableList li.w3 {width: 50%;}#sortableList li.hide {display: none;}</style></head><body><ul id="sortableList"><li id="item1" class="w1" draggable="true">Item 1</li><li id="item2" class="w2" draggable="true">Item 2</li><li id="item3" class="w3" draggable="true">Item 3</li><li id="item4" class="w1" draggable="true">Item 4</li><li id="item5" class="w1" draggable="true">Item 5</li><li id="item6" class="w2" draggable="true">Item 6</li><li id="item7" class="w3" draggable="true">Item 7</li><li id="item8" class="w1" draggable="true">Item 8</li><li id="item9" class="w2" draggable="true">Item 9</li><li id="item10" class="w3" draggable="true">Item 10</li></ul><script src="https://code.jquery.com/jquery-3.6.0.min.js"></script><script>document.addEventListener('DOMContentLoaded', function () {const sortableList = document.getElementById('sortableList');const items = sortableList.querySelectorAll('li');items.forEach((item) => {item.addEventListener('dragstart', dragStart);item.addEventListener('dragover', dragOver);item.addEventListener('drop', drop);item.addEventListener('dragenter', dragEnter);item.addEventListener('dragleave', dragLeave);});function dragStart(e) {e.dataTransfer.setData('text/plain', e.target.id);// setTimeout(() => {// e.target.classList.add('hide');// }, 0);console.log('Drag started:', e.target.id);}function dragOver(e) {e.preventDefault();e.target.classList.add('over');console.log('Drag over:', e.target.id);}function dragEnter(e) {e.preventDefault();console.log('Drag enter:', e.target.id);}function dragLeave(e) {e.target.classList.remove('over');console.log('Drag leave:', e.target.id);}function drop(e) {e.preventDefault();const draggedItemId = e.dataTransfer.getData('text/plain');const draggedItem = document.getElementById(draggedItemId);const targetItem = e.target;if (targetItem !== draggedItem) {const targetIndex = Array.from(items).indexOf(targetItem);const draggedIndex = Array.from(items).indexOf(draggedItem);if (targetIndex > draggedIndex) {targetItem.parentNode.insertBefore(draggedItem,targetItem.nextSibling);} else {targetItem.parentNode.insertBefore(draggedItem, targetItem);}}e.target.classList.remove('over');draggedItem.classList.remove('hide');console.log('Drop:', e.target.id);console.log('在这里加检查宽度方法');checkWidth();}});// 检查宽度function checkWidth(first = true) {//清空空白块if (first) $('#sortableList li.box').remove();//盒子宽度let boxWidth = document.getElementById('sortableList').offsetWidth;//当前li行的宽度let rowLiWidth = 0;//循环lifor (let i = 0; i < $('#sortableList li').length; i++) {var outerWidthWithMargin = $('#sortableList li').eq(i).outerWidth(true);var itemWidth = parseFloat(outerWidthWithMargin.toFixed(2));console.log(i, rowLiWidth, itemWidth);//当前li行的宽度+当前项宽度let RAW = rowLiWidth + itemWidth;//如果当前li行的宽度+当前项宽度大于盒子宽度,则添加空白块,并重新计算。//3是容错宽度。if (RAW >= boxWidth ||(RAW - boxWidth >= -3 && RAW - boxWidth <= 3)) {//宽度大于盒子宽度,则添加空白块,并重新计算。if (RAW > boxWidth) {let thisWidth = boxWidth - rowLiWidth;if (thisWidth > 3) {$('#sortableList li').eq(i).before(`<li class="box" style="width:${thisWidth}px"></li>`);rowLiWidth = 0; //重新计算。checkWidth(false);break;}}rowLiWidth = 0; //重新计算。} else {rowLiWidth += itemWidth;}if (i == $('#sortableList li').length - 1) {let thisWidth = boxWidth - rowLiWidth;$('#sortableList li').eq(i).after(`<li class="box" style="width:${thisWidth}px"></li>`);break;}}}</script></body>
</html>