如何为拖拽元素设置样式

19

有一些事件可以用于处理拖放:

https://developer.mozilla.org/zh-CN/docs/Web/API/HTML_Drag_and_Drop_API

有一个 drag 事件,在元素被拖动期间触发。我可以控制源元素的样式或目标可接受容器的样式,但是如何为浏览器创建的 "ghost" 元素设置样式呢?

我希望在元素位于不可拖动区域上方时从它身上移除 "disabled" 图标,并将其替换为一个 "cursor-move" 图标。

这是目前我得到的代码:

http://jsfiddle.net/YkaCM/

图像描述

5个回答

24

你无法直接对此进行样式设置,因为它是元素在拖动开始时看起来的位图/副本:

http://jsfiddle.net/2EvGP/

编辑:

实际上,你可以通过在拖动开始时短暂更改元素的样式来欺骗它以实现这一目的:http://jsfiddle.net/LULbV/

$('#draggable').bind('dragstart', function (e){

  [Set style here]

  setTimeout(function(){
    [Reset style here]
  }, 1);

  ...

});

这在Chrome 19中完美运行,并且根据您在Firefox 13中的拖动方式显示样式更改。您需要在放置时重置拖动元素的样式。

(请注意,我的计算机速度相当快,因此我不确定这种技巧是否仍适用于慢速计算机)


非常好用,谢谢...在使用setDataImage方法(和其他dataTransfer方法)之前尝试过这个解决方案,但效果不佳。似乎DnD / Data Transfer API中存在一些奇怪的行为。 - Greg Venech

6

一种只使用CSS的替代方法是将元素的:active伪类样式设置为所需的拖动样式。拖动的副本将基于此状态创建。

然而,原始元素将保留此样式,因为浏览器似乎会一直保持其处于:active状态,直到放置操作。 为了避免这种情况,我们可以将样式分配给一个非常短的时间运行的动画。足够让浏览器复制样式但不要太短。Chrome、Safari和Firefox都足够用0.1秒。

https://jsfiddle.net/mLsw5ajr/

$('#draggable').bind('dragstart', function(e) {

  // https://dev59.com/4XE95IYBdhLWcg3wMa51
  var stuff = $(this).clone().wrap('<div></div>').parent().html();

  e.originalEvent.dataTransfer.effectAllowed = 'copy';
  e.originalEvent.dataTransfer.setData('stuff', stuff);
});

$('#draggable').bind('drag', function(e) {
  // here I want to style the ghost element, not the source...    
});

$('#droppable').bind('dragover', function(e) {

  if (e.originalEvent.preventDefault)
    e.preventDefault();

  e.originalEvent.dataTransfer.dropEffect = 'copy';
  return false;
});


$('#droppable').bind('dragenter', function(e) {
  $(this).addClass('over');
});

$('#droppable').bind('dragleave', function(e) {
  $(this).removeClass('over');
});


$('#droppable').bind('drop', function(e) {

  if (e.originalEvent.stopPropagation)
    e.originalEvent.stopPropagation();

  var stuff = $(e.originalEvent.dataTransfer.getData('stuff'));
  stuff.appendTo(this);
  return false;
});
#draggable,
#droppable {
  background: #ccc;
  color: #fff;
  padding: 10px;
  margin: 10px 0 100px;
}

#draggable:active {
  animation: drag_style .1s;
}

#droppable.over {
  background: #000;
}

@keyframes drag_style {
  0% {
    background-color: #fc0;
    color: #000;
  }
  99% {
    background-color: #fc0;
    color: #000;
  }
  100% {
    background-color: #ccc;
  }
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="draggable" draggable="true">
  <p>Drag me to my target</p>
</div>

<div id="droppable">
  <p>Drop me</p>
</div>

我在Firefox中发现的问题是,如果没有其他元素(例如拖放)触发事件,那么该元素将保持 :active状态。为了解决这个问题,我们可以在元素外部触发一个单击事件。

2
不太确定其他浏览器,但是`dataTransfer`对象包含一个叫做`mozCursor`的属性。这允许您在拖动状态下更改光标,但这是一个Mozilla属性。

https://developer.mozilla.org/en-US/docs/Web/API/DataTransfer/mozCursor

可以在以下位置找到使用此功能的示例,设置在 dragstart 上更改(设置为使用默认的“箭头”光标),dragover 上更改(设置为使用自动拖动光标(带有复制的箭头)),以及 dragleave 上重置为使用默认的“箭头”光标。

http://jsfiddle.net/YkaCM/4/


尝试回答以下问题:
JavaScript:在网站上进行拖放操作时如何设置光标?
更新您的拖动悬停,添加以下内容:
$('#droppable').bind('dragover', function (e) {
  $(this).addClass('over'); // new

  ...

http://jsfiddle.net/YkaCM/1/


谢谢,这解决了我原本以为是浏览器故障的问题,但它并没有解决我的疑问 :P - Alex
我认为你无法为“ghost”元素设置样式。在测试时打开Firebug,它似乎没有显示对HTML的任何更改。你有想要实现的例子吗? - JonWarnerNet

1

你基本上想要将特定的样式应用于作为 #droppable 子元素新创建的元素吗?

#droppable div { here your code }

1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接