【问题标题】:Problem with: clone object prior drag & drop问题:在拖放之前克隆对象
【发布时间】:2021-06-12 14:10:35
【问题描述】:

为了将原始元素保持在其位置,我想克隆它并拖动克隆的元素。到目前为止它有效。但是,如果我对要克隆的元素进行“双击”(在拖动之前),我会得到两个克隆的对象,并且 drop 插入两个元素而不是一个元素。有人可以帮我解决这个问题。我尝试为 mouseup 使用额外的事件监听器。我没有找到解决办法。我想它很简单,但目前我没有看到它...感谢您的帮助!

这是我整个代码的一个缩减部分:

let basicElement = document.getElementById('basicElement');
basicElement.addEventListener('mousedown', mousedown);

// press element...
function mousedown(e){
  console.log('mouse down');
  e.stopPropagation();
  
  // clone element
  let elementToDrag = basicElement.cloneNode(true);
  elementToDrag.id = new Date().getMilliseconds();

  // get target
  let divTarget = getElementById('divTarget');

  // add event listener for drag and drop
  basicElement.addEventListener('dragstart', dragstart);
  basicElement.addEventListener('dragend', dragend);

  divTarget.addEventListener('dragover', dragover);
  divTarget.addEventListener('drop', drop);
  
  function dragstart(e){
    console.log('drag start');
    basicElement.classList.add('dragging');
  }

  function dragover(e){
    console.log('drag over');
    e.preventDefault();
  }

  function drop(e){
    console.log('drop');
    divTarget.appendChild(panelToDrag);
  
  }

  function dragend(e){
    console.log('drag end');

    basicElement.classList.remove('dragging');

    basicElement.removeEventListener('dragstart', dragstart);
    basicElement.removeEventListener('dragend', dragend);
    divTarget.removeEventListener('dragover', dragover);
    divTarget.removeEventListener('drop', drop);
  }
}

【问题讨论】:

    标签: javascript drag-and-drop clone


    【解决方案1】:

    感谢您的帮助,它在我的代码中不起作用。但是您给了我以下解决方案的提示:

    let basicElement = document.getElementById('basicElement');
    basicElement.addEventListener('mousedown', mousedown);
    // new flag
    let isDragging = false;
    
    // press element...
    function mousedown(e){
      console.log('mouse down');
      e.stopPropagation();
      // Stop cloning if we have click at it once
      if(isDragging == false) {
        // clone element
        let elementToDrag = basicElement.cloneNode(true);
        elementToDrag.id = new Date().getMilliseconds();
        isDragging = true;
      } else {
        if (isDragging){
          console.log(isDragging);
          return;
        }
      }
    
      
      
    
      // get target
      let divTarget = getElementById('divTarget');
    
      // add event listener for drag and drop
      basicElement.addEventListener('dragstart', dragstart);
      basicElement.addEventListener('dragend', dragend);
    
      divTarget.addEventListener('dragover', dragover);
      divTarget.addEventListener('drop', drop);
      
      function dragstart(e){
        console.log('drag start');
        // Reset isDragging if drag starts
        isDragging = false;
        basicElement.classList.add('dragging');
      }
    
      function dragover(e){
        console.log('drag over');
        e.preventDefault();
      }
    
      function drop(e){
        console.log('drop');
        divTarget.appendChild(panelToDrag);
      }
    
      function dragend(e){
        console.log('drag end');
    
        basicElement.classList.remove('dragging');
    
        basicElement.removeEventListener('dragstart', dragstart);
        basicElement.removeEventListener('dragend', dragend);
        divTarget.removeEventListener('dragover', dragover);
        divTarget.removeEventListener('drop', drop);
      }
    }
    

    【讨论】:

      【解决方案2】:

      mousedown 将创建一个克隆元素,只需单击basicElement 将创建更多克隆元素,这些元素都可以被删除。 mousedown 还创建了一个事件监听器,用于删除每个克隆的元素。

      添加一个标志是一种简单的方法。

      let basicElement = document.getElementById('basicElement');
      basicElement.addEventListener('mousedown', mousedown);
      // new flag
      let isDragging = false;
      
      // press element...
      function mousedown(e){
        console.log('mouse down');
        e.stopPropagation();
        // Stop cloning if we have click at it once
        if(isDragging) {
           return;
        }
        
        // clone element
        let elementToDrag = basicElement.cloneNode(true);
        elementToDrag.id = new Date().getMilliseconds();
      
        // get target
        let divTarget = getElementById('divTarget');
      
        // add event listener for drag and drop
        basicElement.addEventListener('dragstart', dragstart);
        basicElement.addEventListener('dragend', dragend);
      
        divTarget.addEventListener('dragover', dragover);
        divTarget.addEventListener('drop', drop);
        
        function dragstart(e){
          console.log('drag start');
          basicElement.classList.add('dragging');
        }
      
        function dragover(e){
          console.log('drag over');
          e.preventDefault();
        }
      
        function drop(e){
          console.log('drop');
          divTarget.appendChild(panelToDrag);
          // Reset isDragging once it's over
          isDragging = false;
        }
      
        function dragend(e){
          console.log('drag end');
      
          basicElement.classList.remove('dragging');
      
          basicElement.removeEventListener('dragstart', dragstart);
          basicElement.removeEventListener('dragend', dragend);
          divTarget.removeEventListener('dragover', dragover);
          divTarget.removeEventListener('drop', drop);
        }
      }
      

      这解决了问题,但这仅适用于一个目标和一个来源。如果是多对多,则需要考虑注册 id 而不是使用布尔标志。

      【讨论】:

      • 感谢您的帮助!已更改您的代码 - 请参见下文
      • @Harald 看起来不错,很高兴你解决了它。如果您不介意添加一个小的解释摘要以帮助遇到它的其他人。
      猜你喜欢
      • 1970-01-01
      • 2011-10-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-05-13
      • 1970-01-01
      相关资源
      最近更新 更多