Skip to content

关于拖拽api

html
<div id="app">
  <div draggable="true" data-effect="copy"
  style="background: skyblue"  class="subject">
    subject
  </div>
  <div draggable="true" data-effect="copy" style="background: deeppink" class="subject">
    math
  </div>
  <div id="grid" class="grid">
    <div class="cell" data-drop="true">1</div>
    <div class="cell" data-drop="true">2</div>
    <div class="cell" data-drop="true">3</div>
    <div class="cell" data-drop="true">4</div>
  </div>
</div>
css
.subject {
  --height: 30px;
  width: calc(var(--height) * 2);
  height: var(--height);
  text-align: center;
  line-height: var(--height);
}
.grid {
  width: 160px;
  height: 80px;
  padding: 4px;
  display: grid;
  grid-template-columns: 1fr 1fr;
  grid-template-rows: 1fr 1fr;
  grid-gap: 10px;
  border: 1px solid #ccc;
  box-sizing: content-box;
}
.cell {
  display: flex;
  justify-content: center;
  align-items: center;
}
.gray {
  background-color: #ccc;
}
js
const app = document.getElementById('app')
const grid = document.getElementById('grid')
let drapEl
app.ondragstart = (e) => {
  e.dataTransfer.effectAllowed = e.target.dataset.effect
  drapEl = e.target
}
const cellList = grid.querySelectorAll('.cell')
function clearStyle() {
  Array.from(cellList).forEach(el => el.classList.remove('gray'))
}
grid.ondragover = (e) => {
  e.preventDefault()
}

function getDropNode(el) {
  let node = el
  while(node) {
    if (node.dataset && node.dataset.drop) {
      return node
    }
    node = node.parentNode
  }
}

grid.ondragenter = (e) => {
  clearStyle()
  const node = getDropNode(e.target)
  if (node) {
    node.classList.add('gray')
  }
}

grid.ondrop= (e) => {
  clearStyle()
  const node = getDropNode(e.target)
  if (node) {
    if (e.dataTransfer.effectAllowed === 'copy') {
      node.innerHTML = ''
      const cloneEl = drapEl.cloneNode(true)
      cloneEl.dataset.effect =  'move'
      node.appendChild(cloneEl)
    } else {
      node.innerHTML = ''
      const cloneEl = drapEl.cloneNode(true)
      cloneEl.dataset.effect =  'move'
      node.appendChild(cloneEl)
      drapEl.parentNode.innerHTML = ''
    }
  }
}