如何在SortableJS拖拽排序中更新或移除跟随光标浮动元素样式
问题描述
使用SortableJS实现用户排名系统时,拖拽排序条目(例如将第3名移至第4名),跟随光标移动的浮动元素并未更新背景色以匹配新排名,而是保留旧背景色。需解决:
- 如何动态更新该浮动元素的背景色以反映新位置?
- 若无法更新则如何移除该浮动元素?
代码片段
HTML
<script src="https://cdnjs.cloudflare.com/ajax/libs/Sortable/1.15.0/Sortable.min.js"></script> <h2 style="text-align: center;">Classement Drag & Drop</h2> <ul id="sortable-list"> <li data-rank="1"><span class="rank">1.</span> Élément 1</li> <li data-rank="2"><span class="rank">2.</span> Élément 2</li> <li data-rank="3"><span class="rank">3.</span> Élément 3</li> <li data-rank="4"><span class="rank">4.</span> Élément 4</li> </ul>
CSS
body { font-family: Arial, sans-serif; } ul { list-style: none; padding: 0; max-width: 300px; margin: 20px auto; border: 1px solid #ddd; border-radius: 5px; padding: 10px; background: #f9f9f9; } li { background: white; padding: 10px; margin: 5px 0; border: 1px solid #ccc; cursor: grab; display: flex; align-items: center; } li:nth-child(1), .r1 { background-color: rgba(255, 204, 0, 0.75); box-shadow: 0 2px 8px rgba(255, 204, 0, 0.9); } li:nth-child(1)::before, .r1::before { content: "🥇"; } li:nth-child(2), .r2 { background-color: rgba(209, 209, 209, 0.75); box-shadow: 0 2px 8px rgba(209, 209, 209, 0.9); } li:nth-child(2)::before, .r2::before { content: "🥈"; } li:nth-child(3), .r3 { background-color: rgba(205, 127, 50, 0.75); box-shadow: 0 2px 8px rgba(205, 127, 50, 0.9); } li:nth-child(3)::before, .r3::before { content: "🥉"; } .rank { font-weight: bold; margin-right: 10px; } .sortable_ghost { opacity: 0.5; background: #e0e0e0; }
JavaScript
document.addEventListener("DOMContentLoaded", function() { var sortable = new Sortable(document.getElementById("sortable-list"), { animation: 150, ghostClass: "sortable_ghost", onEnd: function() { updateRanks(); } }); function updateRanks() { document.querySelectorAll("#sortable-list li").forEach((li, index) => { li.dataset.rank = index + 1; li.querySelector(".rank").textContent = (index + 1) + "."; }); } });
问题效果展示

解决方案
方法1:动态更新浮动元素背景色(推荐)
SortableJS的浮动元素是原元素的克隆体,可通过onMove事件实时获取插入位置,为克隆体添加对应排名的样式类:
- 修改JavaScript代码,添加
onMove事件监听:
document.addEventListener("DOMContentLoaded", function() { var sortable = new Sortable(document.getElementById("sortable-list"), { animation: 150, ghostClass: "sortable_ghost", onEnd: function() { updateRanks(); }, onMove: function(evt) { // 获取当前插入位置的排名 const targetSiblings = Array.from(evt.related.parentElement.children); const targetIndex = targetSiblings.indexOf(evt.related); const newRank = evt.willInsertAfter ? targetIndex + 2 : targetIndex + 1; // 获取浮动元素并更新样式类 const ghostEl = document.querySelector('.sortable_ghost'); ghostEl.classList.remove('r1', 'r2', 'r3'); if (newRank <= 3) { ghostEl.classList.add(`r${newRank}`); } } }); function updateRanks() { document.querySelectorAll("#sortable-list li").forEach((li, index) => { li.dataset.rank = index + 1; li.querySelector(".rank").textContent = (index + 1) + "."; // 同步更新原元素的排名类 li.classList.remove('r1', 'r2', 'r3'); if ((index + 1) <= 3) { li.classList.add(`r${index + 1}`); } }); } });
- 调整CSS,移除
sortable_ghost的背景色,避免覆盖排名类样式:
.sortable_ghost { opacity: 0.5; /* 移除原有background属性 */ }
方法2:移除浮动元素
如果不需要显示浮动元素,可通过以下两种方式实现:
- CSS隐藏:
.sortable_ghost { display: none !important; }
- 禁用ghost类:
var sortable = new Sortable(document.getElementById("sortable-list"), { animation: 150, ghostClass: "", // 清空ghost类配置 onEnd: function() { updateRanks(); } });
内容的提问来源于stack exchange,提问作者Matrix
相关产品推荐
相关产品推荐

