基于jQuery UI实现两个可排序列表的拖拽分配(非移动)方案咨询
Solution: Drag-and-Drop Tag Assignment with Sortable Lists
Great question! This is a perfect use case for combining jQuery UI's sortable, draggable, and droppable components. Let's build out the exact behavior you're looking for, step by step:
Core Implementation Logic
- Keep your existing list sorting functionality intact.
- Make each list item draggable using a clone helper (so the original item stays in its list during the drag).
- Turn each list item into a droppable target that only accepts items from the opposite list.
- On drop, add the dragged item's name as a tag to the target item, then let the clone revert back to its original position.
Full Working Code
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <script src="https://code.jquery.com/ui/1.12.0/jquery-ui.min.js"></script> <style> .list1, .list2 { list-style-type: none; width: 40%; float: left; margin-right: 30px; } .list1 .item, .list2 .item { border: 1px solid gray; padding: 10px; margin: 5px 0; position: relative; } .sortable-placeholder { border: 1px dotted #e6e6e6; height: 40px; color: #fff; margin: 5px 0; } /* Styled tags for assigned items */ .tag { display: inline-block; background: #f0f0f0; padding: 2px 6px; border-radius: 4px; font-size: 0.8em; margin-left: 8px; margin-top: 4px; } /* Hover effect for valid drop targets */ .ui-state-highlight { background: #e8f4fa; } </style> <ul class="list1"> <li class="item">Item 1</li> <li class="item">Item 2</li> <li class="item">Item 3</li> </ul> <ul class="list2"> <li class="item">Item 4</li> <li class="item">Item 5</li> <li class="item">Item 6</li> </ul> <script> // Keep your original sortable configuration var sortableOptions = { cursor: "move", placeholder: "sortable-placeholder", tolerance: "pointer", opacity: 0.8, scroll: true, scrollSensitivity: 100 }; $('.list1').sortable(sortableOptions); $('.list2').sortable(sortableOptions); // Make all items draggable (clone helper keeps original in place) $('.item').draggable({ helper: 'clone', revert: 'invalid', // Revert clone if dropped outside a valid target opacity: 0.7, cursor: 'copy' // Visual cue this is a copy operation, not a move }); // Configure list1 items to accept drops from list2 $('.list1 .item').droppable({ accept: '.list2 .item', hoverClass: 'ui-state-highlight', drop: function(event, ui) { const draggedItemText = ui.draggable.text().trim(); // Append the dragged item as a tag to the target $(this).append(`<span class="tag">${draggedItemText}</span>`); } }); // Configure list2 items to accept drops from list1 (bidirectional support) $('.list2 .item').droppable({ accept: '.list1 .item', hoverClass: 'ui-state-highlight', drop: function(event, ui) { const draggedItemText = ui.draggable.text().trim(); $(this).append(`<span class="tag">${draggedItemText}</span>`); } }); </script>
Key Features Breakdown
- Sortable Lists: Your original sorting functionality is fully preserved—users can still reorder items within each list as needed.
- Non-Destructive Drag: Using
helper: 'clone'ensures the original item never leaves its list during the drag operation. Therevert: 'invalid'makes the clone disappear cleanly if dropped outside a valid target. - Bidirectional Assignment: Both lists can receive items from the other, just like you requested.
- Multiple Assignments: The same item can be dragged to multiple targets in the opposite list (no restrictions on repeated assignments).
- Visual Feedback: The
hoverClassgives users a clear visual cue when dragging over a valid drop target, and thecursor: 'copy'signals that this is a tag assignment, not a move.
Optional: Prevent Duplicate Tags
If you want to stop users from adding the same tag multiple times to a single item, add this check inside the drop function:
// Inside drop event handler const draggedItemText = ui.draggable.text().trim(); if (!$(this).find(`.tag:contains("${draggedItemText}")`).length) { $(this).append(`<span class="tag">${draggedItemText}</span>`); }
内容的提问来源于stack exchange,提问作者Szebyku
相关产品推荐
相关产品推荐

