使用 html5 可拖动属性时保留被拖动 A 元素的外观

Posted

技术标签:

【中文标题】使用 html5 可拖动属性时保留被拖动 A 元素的外观【英文标题】:Preserve appearance of dragged A element when using html5 draggable attribute 【发布时间】:2015-02-23 17:02:21 【问题描述】:

当使用'draggable' html5 属性时,如何保持被拖动的A 元素的外观。在某些浏览器(Safari 和 Chrome)上,当拖动锚点时,拖动的助手会被拖动元素的浏览器原生实现替换,如屏幕截图所示:

拖动DIV时

拖动A时

HTML

<div class="draggable">Draggable DIV</div>
<a href="" class="draggable">Draggable A</a>

CSS

$('.draggable').attr('draggable', true);

这是我为演示此问题而组装的快速 JSBin http://jsbin.com/pihayeceza/1/edit

谢谢

【问题讨论】:

也许不是真正的解决方案,但删除 href 属性似乎可以纠正它。我猜浏览器在拖动带有 href 的锚点时的默认行为是将 url 作为占位符,这会覆盖没有 href 时发生的情况。 这可能会有所帮助:developer.mozilla.org/en-US/docs/Web/Guide/HTML/… 我很好奇你为什么使用jQuery来添加draggable属性?它可能与上下文无关,但在我看来,您最好将draggable="true" 添加到 HTML 元素中? @Billy 使用 jQuery 组装 jsbin 示例对我来说更容易,仅此而已 【参考方案1】:

我可以使用DataTransfer.setDragImage 保留被拖动元素的外观。如果我将以下代码添加到您的 jsbin 实例中的 javascript,它适用于 Firefox、Chrome 和 Safari:

$('a.draggable').on('dragstart', function (ev) 
  var dt = ev.originalEvent.dataTransfer;
  // In IE browsers, setDragImage does not exist. However, the issue we are 
  // trying to fix does not happen in these broswers. So if setDragImage is not
  // available, then just don't do anything.
  if (dt.setDragImage) 
    dt.setDragImage(ev.target, 0, 0);

);

事件的dataTransfer 字段有一个与拖动操作关联的DataTransfer 对象。您必须从原始 DOM 事件而不是 jQuery 事件包装器中获取它,所以ev.originalEvent.dataTransfer

对于 IE 浏览器,setDragImage 不存在,但问题中报告的问题一开始就没有发生,所以如果setDragImage 不存在,我们就不会调用它。

带有更新代码的bin。

【讨论】:

这看起来是一种非常简单的方法来完成我设定的任务,但 caniuse.com (caniuse.com/#feat=dragndrop) 声明 Internet Explorer 不支持 setDragImage 方法。有什么解决方法的建议吗? 太棒了!非常感谢!【参考方案2】:

出现这个问题是因为拖动带有 href 属性的链接的默认行为是创建一个包含要用作拖动占位符的 url 的图像。您可以通过删除 href 属性来解决此问题,但是,要解决此问题而无需删除 href 属性,您可以使用 mousedown/up 事件处理程序删除该属性,然后重新添加它,使锚点可点击*。

$('.draggable').attr('draggable', true).on('mousedown', function () 
  if ($(this).is('a')) 
    $(this).data('href', this.href);
    $(this).removeAttr('href');
  
).on('mouseup', function () 
  if ($(this).is('a')) 
    $(this).attr('href', $(this).data('href'));
  
).on('click', function () 
  console.log(this.href);
);
.draggable 
  margin: 10px;
  display: block;
  width: 200px;
  background: #fafafa;
  color: #333;
  text-decoration: none;
  height: 40px;
  border: 1px solid #eaeaea;
  line-height: 40px;
  text-align: center;
  cursor: move;
  border-radius: 20px;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class="draggable">Draggable DIV</div>
  <a href="http://www.google.com" target="_blank" class="draggable">Draggable A</a>

*注意:stack sn-ps 不允许您点击链接。

【讨论】:

我希望将 event.dataTransfer.effectAllowed 设置为 copy 可以解决这个问题,但是,它似乎在 chrome 中没有任何效果。 如果我在 Internet Explorer 中找不到 ev.originalEvent.dataTransfer 支持的解决方法,我想我会使用这个解决方案。您是否在浏览器中测试过这个解决方案,看看哪些浏览器支持它? 不,我没有。只是铬。【参考方案3】:

用 div 包裹你的锚标签,并在锚标签上设置 draggable="false"。

<div class="draggable">
    <a href="" draggable="false">Draggable A</a>
</div>

您需要额外的样式来防止按钮/链接看起来是蓝色和带下划线的。

.draggable a 
  color: inherit;
  text-decoration: inherit;

在这里修改了你的 jsbin http://jsbin.com/rebayif/edit

【讨论】:

这对我很有帮助,因为我的 之外已经有一个 draggable="true" 元素。所以只需在 上添加一个 draggable="false" 就为我解决了这个问题。谢谢! +1

以上是关于使用 html5 可拖动属性时保留被拖动 A 元素的外观的主要内容,如果未能解决你的问题,请参考以下文章

HTML5拖放(Drag和Drop)元素使用详解

如何使可拖动元素在拖放时保持在新位置(HTML5 不是 jQuery)?

HTML5新属性-----拖放

HTML5拖拽/拖放(drag & drop)详解

HTML5 DragEvent学习+制作一个可以拖动的DIV

HTML5 DragEvent学习+制作一个可以拖动的DIV