首页 > 解决方案 > 拖放的几个问题

问题描述

我有类似附加代码的东西,可以在列表元素之间拖放一些绿色 div。

有两个问题我似乎无法解决:

1) 较大的“Take Me”div 中的“ghost”拖动图像几乎不可见。用户几乎不知道拖动了什么。这可以以某种方式改变吗?

2) 放置目标是鼠标指针下的目标。这是非常合乎逻辑的,但它使用户难以理解果岭将被丢弃的位置。如果它被底部拖动,那么当释放鼠标按钮时,绿色会向下跳跃。有没有办法让重影图像的顶部捕捉到指针?

在最终的应用程序中会有许多绿色的 div 并且用户应该能够将它们排列在一起而没有重叠,因此清楚地了解被拖动的内容和精确放置是很重要的。

我最好不要使用拖动事件并以老式方式手动实现拖放(很可能使用某种库)?

我只需要对最新浏览器的支持,到目前为止,我只在 Windows 上尝试过 Chrome 和 FF。

function initDragDrop(){

    initDragDrop.dragged = null;

    // Dragged
    $('div')
        .on('dragstart',
            function(event) {

                initDragDrop.dragged = this;
                initDragDrop.dragged.style.opacity = 0.5;
                event.originalEvent.dataTransfer.setData('text/plain', 'dummy'); 
            })
        .on('dragend', function( event ) {

            event.target.style.opacity = '';
        });
        
    // Drop targets
    $('li')
        .on('dragenter', function(event) {

            event.preventDefault(); 
        })
        .on('drop dragdrop', function(event){

            event.preventDefault(); 
            event.stopPropagation();

            event.target.classList.remove('dragover');
            if ( initDragDrop.dragged ) {

                initDragDrop.dragged.style.opacity = '';
                $(this).append($(initDragDrop.dragged));
                initDragDrop.dragged = null;
            }
        })
        .on('dragover', function(event) {

            event.target.classList.add('dragover');
            event.preventDefault(); 
        })
        .on('dragleave', function(event) {

            event.target.classList.remove('dragover');
        });
}

initDragDrop();
ul {
  width: 30em;
  display: block;
}
ul.small {
  margin-top: 4em;
  width: 10em;
}
li {
  height: 2em;
  border: 1px solid grey;
}
li.dragover {
  background: #ddd;
}
div {
  background-color: lightgreen;
  border: 2px solid darkgreen;
  position: relative;
  margin: 0;
  width: 90%;
  height: 5em;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul>
<li></li>
<li></li>
<li><div draggable="true">
Take Me
</div></li>
<li></li>
</ul>
<ul class="small">
<li></li>
<li></li>
<li><div draggable="true">
Take Me too
</div></li>
<li></li>
<li></li>
<li></li>
</ul>

标签: javascripthtml

解决方案


您不能直接设置拖动元素的样式。一旦开始拖动,它就是此时元素外观的位图副本。

但是,您可以在拖动开始之前更改其样式(或类),然后立即将其恢复。因此,我们应该能够在“屏幕截图”发生之前将其风格化,使其处于良好的位置。

这是样式有效但定位无效的尝试……我试图弄清楚:

(function initDragDrop() {
  initDragDrop.dragged = null;

  // Dragged
  $('div')
    .on('dragstart', function(event) {

      initDragDrop.dragged = this;
      initDragDrop.dragged.classList.add('ghost');
      event.originalEvent.dataTransfer.setData('text/plain', 'dummy');

      // Set style for the element before dragging it
      var elm = event.target;
      elm.classList.add('dragged');
      elm.style.top = (event.clientY) - 5 + 'px';
      elm.style.left = (event.clientX) - 5 + 'px';
      
      // Reset style after drag has started
      setTimeout((function(elm) {
        return function() {
          elm.classList.remove('dragged');
          elm.style.removeProperty('top');
          elm.style.removeProperty('left');
        }
      })(elm), 1000);

    })
    .on('dragend', function(event) {
      // event.target.style.opacity = ''; // Not used
    });

  // Drop targets
  $('li')
    .on('dragenter', function(event) {
      event.preventDefault();
    })
    .on('drop dragdrop', function(event) {
      event.preventDefault();
      event.stopPropagation();
      event.target.classList.remove('dragover');
      if (initDragDrop.dragged) {
        initDragDrop.dragged.classList.remove('ghost');
        $(this).append($(initDragDrop.dragged));
        initDragDrop.dragged = null;
      }
    })
    .on('dragover', function(event) {
      event.target.classList.add('dragover');
      event.preventDefault();
    })
    .on('dragleave', function(event) {
      event.target.classList.remove('dragover');
    });
})();
ul {
  width: 30em;
  display: block;
}

ul.small {
  margin-top: 4em;
  width: 10em;
}

li {
  height: 2em;
  border: 1px solid grey;
}

li.dragover {
  background: #ddd;
}

div {
  background-color: lightgreen;
  border: 2px solid darkgreen;
  position: relative;
  margin: 0;
  width: 90%;
  height: 5em;
}

.ghost {
  opacity: 0.5;
}

.dragged {
  display: block;
  position: fixed;
  background-color: red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul>
  <li></li>
  <li></li>
  <li>
    <div draggable="true">
      Take Me
    </div>
  </li>
  <li></li>
</ul>
<ul class="small">
  <li></li>
  <li></li>
  <li>
    <div draggable="true">
      Take Me too
    </div>
  </li>
  <li></li>
  <li></li>
  <li></li>
</ul>


推荐阅读