拖放带来的几个问题

时间:2018-12-19 15:24:06

标签: javascript html

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

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

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

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>

1 个答案:

答案 0 :(得分:1)

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

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

这是一种尝试样式的方法,但是没有定位的方法……我试图弄清楚:

(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>