更新显示的数字以匹配其在纯 javascript 中元素顺序的位置

Ben*_*ell 5 javascript

我有代码允许我拖放以重新排列项目并将它们从一个容器移动到另一个容器,但我也想更新 span 标签内的数字以匹配它的位置。

例如,“科罗拉多”在 0 位置,但是当我将它拖到“犹他州”之后时,我想更新“蒙大拿州”以使其旁边有“0”,“犹他州”为“1”,“科罗拉多州”为“2”,但我不知道该怎么做。

这是 JS 小提琴:https : //jsfiddle.net/benschnell/0wbfoqk9/

const draggables = document.querySelectorAll('.draggable')
const containers = document.querySelectorAll('.container')

draggables.forEach(draggable => {
  draggable.addEventListener('dragstart', () => {
    draggable.classList.add('dragging')
  })

  draggable.addEventListener('dragend', () => {
    draggable.classList.remove('dragging')
  })
})

containers.forEach(container => {
  container.addEventListener('dragover', dragOver);
})

function dragOver(e) {
   e.preventDefault()
    const afterElement = getDragAfterElement(this, e.clientY)
    const draggable = document.querySelector('.dragging')
    if (afterElement == null) {
      this.appendChild(draggable)
    } else {
      this.insertBefore(draggable, afterElement)
    }
}

function getDragAfterElement(container, y) {
  const draggableElements = [...container.querySelectorAll('.draggable:not(.dragging)')]

  return draggableElements.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
}
Run Code Online (Sandbox Code Playgroud)
<ul class="container">
  <li class="draggable" draggable="true"><span>0</span> Colorado</li>
  <li class="draggable" draggable="true"><span>1</span> Montana</li>
  <li class="draggable" draggable="true"><span>2</span> Utah</li>
  <li class="draggable" draggable="true"><span>3</span> Montana</li>
  <li class="draggable" draggable="true"><span>4</span> Wyoming</li>
</ul>

<ul class="container">
  <li class="draggable" draggable="true"><span>0</span> Maine</li>
  <li class="draggable" draggable="true"><span>1</span> North Carolina</li>
  <li class="draggable" draggable="true"><span>2</span> Florida</li>
  <li class="draggable" draggable="true"><span>3</span> Virginia</li>
  <li class="draggable" draggable="true"><span>4</span> New York</li>
</ul>
Run Code Online (Sandbox Code Playgroud)

Sas*_*cha 0

我在可拖动的事件侦听器中添加了更新数字的调用。

  draggable.addEventListener('dragend', (e) => {
    draggable.classList.remove('dragging');
    dragUpdateNr();
  })
Run Code Online (Sandbox Code Playgroud)

该函数首先查找 UL,然后与 foreach 一起使用。我在这里搜索所有 LI。在这些已建立的元素上,我使用一个简单的 for 循环,并将第一个子元素(这是带有数字的 SPAN)中的 textContent 设置为循环中的索引。

function dragUpdateNr() {
    let uls = document.querySelectorAll('ul.container');
    
    uls.forEach(ul => {
        let lis = ul.querySelectorAll('li.draggable');
        for (let i=0; i<lis.length; i++) {
            let li = lis[i];
            li.firstChild.textContent = i;
        }
    });
}
Run Code Online (Sandbox Code Playgroud)

这是用于测试的扩展JSFifiddle,这里是带有这 2 个扩展的漏洞代码。

  draggable.addEventListener('dragend', (e) => {
    draggable.classList.remove('dragging');
    dragUpdateNr();
  })
Run Code Online (Sandbox Code Playgroud)
function dragUpdateNr() {
    let uls = document.querySelectorAll('ul.container');
    
    uls.forEach(ul => {
        let lis = ul.querySelectorAll('li.draggable');
        for (let i=0; i<lis.length; i++) {
            let li = lis[i];
            li.firstChild.textContent = i;
        }
    });
}
Run Code Online (Sandbox Code Playgroud)
const draggables = document.querySelectorAll('.draggable')
const containers = document.querySelectorAll('.container')

draggables.forEach(draggable => {
  draggable.addEventListener('dragstart', () => {
    draggable.classList.add('dragging')
  })

  draggable.addEventListener('dragend', (e) => {
    draggable.classList.remove('dragging');
    dragUpdateNr();
  })
})

containers.forEach(container => {
    container.addEventListener('dragover', dragOver);
})

function dragOver(e) {
     e.preventDefault()
    const afterElement = getDragAfterElement(this, e.clientY)
    const draggable = document.querySelector('.dragging')
    if (afterElement == null) {
      this.appendChild(draggable)
    } else {
      this.insertBefore(draggable, afterElement)
    }
}

function getDragAfterElement(container, y) {
  const draggableElements = [...container.querySelectorAll('.draggable:not(.dragging)')]

  return draggableElements.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
}

function dragUpdateNr() {
    let uls = document.querySelectorAll('ul.container');
    
    uls.forEach(ul => {
        let lis = ul.querySelectorAll('li.draggable');
        for (let i=0; i<lis.length; i++) {
            let li = lis[i];
            li.firstChild.textContent = i;
        }
    });
}
Run Code Online (Sandbox Code Playgroud)