原生js实现拖拽替换

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
  <style>
    div {
       100px;
      height: 100px;
      text-align: center;
      line-height: 100px;
      border: 1px solid red;
      margin-right: 15px;
    }
  </style>
</head>

<body>
  <div class="d1" draggable="true">div1</div>
  <div draggable="true" class="d2">div2</div>
  <div draggable="true" class="d3">div3</div>
  <div draggable="true" class="d4">div4</div>
  <div draggable="true" class="d5">div5</div>
</body>
<script>
  var div = document.getElementsByTagName('div')
  var container = null; // 存放拖拽元素的容器
  for (let i = 0; i < div.length; i++) {
    // 开始拖拽时把元素用容器存放
    div[i].ondragstart = function () {
      container = this;
    }
    // 默认当我dragover的时候会阻止我做drop操作,这里取消默认事件
    div[i].ondragover = function (e) {
      e.preventDefault()
    }
    // 当拖动结束的时候,给拖动的div所在位置的下面的div做drop事件
    div[i].ondrop = function () {
      if (container != null && container != this) {
        let temp = document.createElement('div')
        document.body.replaceChild(temp, this)
        document.body.replaceChild(this, container)
        document.body.replaceChild(container, temp)
      }
    }
  }
</script>

</html>

  再来一个参考

<!DOCTYPE html>
<html>

<head>
  <title></title>
  <style>
    body {
      margin: 0;
    }

    .box {
      display: flex;
      justify-content: flex-start;
      flex-wrap: wrap;
    }

    .card {
      flex: 1;
      min- 26%;
      max- calc(33.3% - 40px);
      height: 200px;
      margin: 30px 10px;
      position: relative;
      padding: 10px;
      box-shadow: 0 2px 5px 0 #999;
      border-radius: 5px;
      border: 2px dashed transparent;
    }

    .card-name {
      position: absolute;
      top: 10px;
      left: 10px;
      line-height: 20px;
      height: 20px;
    }

    .card-img {
      position: relative;
      padding-top: 20px;
      box-sizing: border-box;
       100%;
      height: 100%;
      overflow: hidden;
    }

    .card-img img {
       100%;
      height: 100%;
    }

    .dragging-over * {
      pointer-events: none;
    }
  </style>
</head>

<body>
  <div class="box">
  </div>
</body>
<script>
  const htmlArr = [
    { title: '示例1-风景', src: 'https://ss3.bdstatic.com/70cFv8Sh_Q1YnxGkpoWK1HF6hhy/it/u=2756575517,833879878&fm=200&gp=0.jpg' },
    { title: '示例2-风景', src: 'https://ss1.bdstatic.com/70cFuXSh_Q1YnxGkpoWK1HF6hhy/it/u=328517395,2303970886&fm=26&gp=0.jpg' },
    { title: '示例3-风景', src: 'https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1554369684535&di=1c1dbfbd4545ad0a05e12cbbbfe3eeef&imgtype=0&src=http%3A%2F%2Fpic41.nipic.com%2F20140601%2F18681759_143805185000_2.jpg' },
    { title: '示例4-风景', src: 'https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1554369684534&di=d6e34af6fce6564f9df6c4eecc27d2ce&imgtype=0&src=http%3A%2F%2Fimgsrc.baidu.com%2Fimgad%2Fpic%2Fitem%2F4d086e061d950a7b9138ff1000d162d9f3d3c9d1.jpg' },
  ]

  let fromDom = null,
    toDom = null,
    lastDom = null;

  function handleDragStart(e, dom) {
    lastDom = fromDom = dom;
    dom.style.border = "2px dashed #999";
    dom.style.opacity = 0.4;
  }

  function handleDrop(e, dom) {
    //只有在可放置的元素上面松开鼠标才会触发drop事件
    console.log('drop');
    dom.style.opacity = "";
    fromDom = null;
    toDom = null;
  }
  function handleDragEnd(e, dom) {
    //拖拽时松开鼠标就会会触发dragend事件
    console.log('end');
    dom.style.border = "2px dashed transparent";
    dom.style.opacity = "";
    toDom = null;
  }
  function handleDragEnter(e, dom) {
    toDom = dom;
    if (fromDom == lastDom) {
      //第一次调换
      swapDom(lastDom, toDom);
      lastDom = toDom;
    } else {
      //第N+1次调换,要先把上一个div的东西还原回去,再跟第三个div互换
      //这个防止enter多次触发
      if (lastDom == toDom) { return; }
      swapDom(fromDom, lastDom);
      swapDom(fromDom, toDom);
      lastDom = toDom;
    }
  }
  function handleDragOver(e, dom) {
    //默认无法把元素放置到其他元素当中,所以需要prevent
    e.preventDefault();
    e.dataTransfer.effectAllowed = "move";
  }

  function swapDom(a, b) {
    //a和b的innerHTML互换
    let temp = a.innerHTML;
    a.innerHTML = b.innerHTML;
    b.innerHTML = temp;
  }

  //生成dom结构
  function createDom(arr) {
    let body = document.getElementsByClassName('box')[0];
    let html = [];
    for (let i = 0, len = arr.length; i < len; i++) {
      html.push(template(arr[i].title, arr[i].src));
    }
    body.innerHTML = html.join('');
  }

  //html模板,根据该模板动态生成dom节点
  function template(title, src) {
    let tpl = `<div class="card" draggable="true" ondragstart="handleDragStart(event,this)" ondragover="handleDragOver(event,this)" ondragend="handleDragEnd(event,this)" ondrop="handleDrop(event,this)" ondragenter="handleDragEnter(event,this)">
            <span class="card-name">
                ${title}
            </span>
            <div class="card-img">
                <img src="${src}" draggable="false" alt="">
            </div>
        </div>`
    return tpl;
  }
  window.onload = function () {
    createDom(htmlArr);
  }
</script>

</html>

  

原文地址:https://www.cnblogs.com/webSong/p/12437042.html