如何设置拖动元素的样式

问题描述 投票:0回答:6

我可以使用一些事件来处理拖放:

https://developer.mozilla.org/en/DragDrop/Drag_and_Drop

有一个

drag
事件,在拖动元素时会触发该事件。我可以控制源元素样式或目标可放置容器,但如何设置浏览器创建的“幽灵”元素的样式?

当元素位于不可拖动区域上方时,我想从中删除“禁用”图标,并将其替换为“光标移动”图标

这是我到目前为止所拥有的:

http://jsfiddle.net/YkaCM/

enter image description here

javascript html drag-and-drop dom-events
6个回答
26
投票

您无法直接设置其样式,因为它是拖动开始时元素外观的位图/副本:

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 中拖动的方式显示样式变化。您需要在放置时重置拖动元素的样式。

(注意我有一台非常快的计算机,所以我不确定这个黑客是否仍然可以在慢速机器上工作)


8
投票

另一种方法是仅使用 CSS,将元素的

:active
伪类设置为所需的拖动样式。拖动的副本将根据此状态创建。

但是,原始元素将保留这种样式,因为浏览器似乎会保留它

:active
直到删除。 为了避免这种情况,我们可以在运行很短时间的动画中分配样式。足以让浏览器复制样式,但不能太短。对于 Chrome、Safari 和 Firefox 来说 0.1 秒似乎足够了。

https://jsfiddle.net/mLsw5ajr/

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

  // http://stackoverflow.com/questions/2419749/get-selected-elements-outer-html
  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
。为了解决这个问题,我们可以触发元素外部的点击。


3
投票

不太确定其他浏览器,但是

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/


2
投票

您可以向正在拖动的元素添加一个类,从而允许您根据需要设置其样式。像这样:

element.addEventListener("dragstart", (event) => {
  event.currentTarget.classList.add("dragging");
});

签出https://developer.mozilla.org/en-US/docs/Web/API/DataTransfer/setData


1
投票

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

#droppable div { here your code }

0
投票

添加一个 setTimeout 来删除该类就可以了! 当浏览器进行位图复制时,当我们在dragstart处设置类时,副本包含该类。超时会删除原始元素上的类,而不是幽灵。

element.addEventListener("dragstart", (event) => {
  event.currentTarget.classList.add("dragging");
  setTimeout(() => {
    event.currentTarget.classList.remove('dragging')
  }, 10)
});

10 ms 是任意的。我不知道最好的延迟。

© www.soinside.com 2019 - 2024. All rights reserved.