如何限制拖拽元素仅在所属行(句子组)内进行拖拽操作
解决方案:限制拖拽仅在同一句子组内生效
这个问题我之前做类似交互时也碰到过,核心就是得给每个拖拽组加上「边界校验」,确保只有同一.container(句子组)内的元素才能互相拖拽交换。咱们只需要在原有拖拽逻辑里加两步就能搞定,具体修改如下:
1. 修改JavaScript逻辑
主要新增「记录源元素所在组」和「校验目标元素是否同组」两个关键步骤:
document.addEventListener('DOMContentLoaded', (event) => { var dragSrcEl = null; var dragSrcContainer = null; // 新增:存储拖拽源所属的句子组容器 function handleDragStart(e) { this.style.opacity = '0.4'; dragSrcEl = this; // 新增:记录当前拖拽元素的父容器(也就是对应的句子组) dragSrcContainer = this.parentElement; e.dataTransfer.effectAllowed = 'move'; e.dataTransfer.setData('text/html', this.innerHTML); } function handleDragOver(e) { if (e.preventDefault) { e.preventDefault(); } e.dataTransfer.dropEffect = 'move'; return false; } function handleDragEnter(e) { this.classList.add('over'); } function handleDragLeave(e) { this.classList.remove('over'); } function handleDrop(e) { if (e.stopPropagation) { e.stopPropagation(); // 阻止浏览器默认跳转行为 } // 新增:校验目标元素和源元素是否属于同一组 const dropTargetContainer = this.parentElement; if (dragSrcContainer !== dropTargetContainer) { return false; // 跨组拖拽直接拒绝,不执行交换逻辑 } if (dragSrcEl != this) { dragSrcEl.innerHTML = this.innerHTML; this.innerHTML = e.dataTransfer.getData('text/html'); } return false; } function handleDragEnd(e) { this.style.opacity = '1'; items.forEach(function(item) { item.classList.remove('over'); }); } let items = document.querySelectorAll('.container .box'); items.forEach(function(item) { item.addEventListener('dragstart', handleDragStart, false); item.addEventListener('dragenter', handleDragEnter, false); item.addEventListener('dragover', handleDragOver, false); item.addEventListener('dragleave', handleDragLeave, false); item.addEventListener('drop', handleDrop, false); item.addEventListener('dragend', handleDragEnd, false); }); });
2. CSS与HTML无需修改
你的现有布局已经用独立的.container包裹每个句子组,正好适配这个校验逻辑,所以CSS和HTML保持原样即可。后续要添加更多句子组,直接复制.container模块就行。
效果说明
修改完成后,用户尝试把A组的单词拖到B组时,拖拽事件会被直接拦截,不会发生元素交换;只有同一组内的单词(包括红色边框的无用单词位置)才能互相拖拽,完全符合你的需求。
内容的提问来源于stack exchange,提问作者zotzotzot
相关产品推荐
相关产品推荐

