【问题标题】:Preserve appearance of dragged A element when using html5 draggable attribute使用 html5 可拖动属性时保留被拖动 A 元素的外观
【发布时间】: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 时发生的情况。
  • 我很好奇你为什么使用jQuery来添加draggable属性?它可能与上下文无关,但在我看来,您最好将draggable="true" 添加到 HTML 元素中?
  • @Billy 使用 jQuery 组装 jsbin 示例对我来说更容易,仅此而已

标签: javascript html anchor draggable


【解决方案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

猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-03-25
  • 1970-01-01
  • 1970-01-01
  • 2012-09-17
  • 1970-01-01
相关资源
最近更新 更多