跨浏览器拖动前清除内容选择的方法

Cross-browser method to clear content selection before dragging

一直在尝试解决在执行 HTML5 拖动之前立即清除内容 selection 所涉及的各种跨浏览器问题。

当前进度在这里: https://jsfiddle.net/kamelkev/36ek328t/

$(document).ready(function() {
  var down = 0;

  $(document.body).on('dragstart.draggable', function(event) {
    if (!$(event.target).attr('draggable')) {
      event.preventDefault();
    }

    return;
  });

  $('div[draggable]').on('dragstart', function(event) {
    event.originalEvent.dataTransfer.setData("Text", '');
  });

  $('div[draggable]').on('mousedown.selections', function(event) {
    down = 1;

    return true;
  });

  $('div[draggable]').on('mouseup.selections', function(event) {
    down = 0;

    return true;
  });

  $('div[draggable]').on('mousemove.selections', function(event) {
    var doc = event.target.ownerDocument;

    if (down) {
      if (doc.selection) {
        doc.selection.empty();
      }
      else if (doc.getSelection) {
        if (doc.getSelection().empty) {  // Chrome
          doc.getSelection().empty();
        }
        else if (doc.getSelection().removeAllRanges) {  // Firefox
          doc.getSelection().removeAllRanges();
        }
      }

      down = 0;
    }
    else {
      down = 0;
    }

    return true;
  });
});

在Chrome/Safari/Firefox中你会注意到selecting all (command-a)的内容在“thing2”上执行拖动不仅会清除 selection,还会允许拖动事件继续进行。出于某种原因,IE 清除了 selection,但随后似乎取消了后续的 dragstart 事件。

我可以在 Microsoft 自己的文档或其他地方找到对此类行为的几乎零引用。非常感谢任何指点。

我已经尝试了很多方法来解决这个问题,将我的各种 selection 清除代码移动到不同的事件中,等等,但没有成功。

关于如何解决这个问题有什么想法吗?

我这样做是为了避免在执行 HTML5 拖动时出现拖动图像问题。您在执行 HTML5 拖动时看到的“重影”图像是从所有拖动内容的总和部分生成的,而不是从被拖动的元素生成的。如果用户碰巧执行了 select-all,那么随后生成的拖动图像将使用幻影图像的所有内容,而不仅仅是被拖动元素的内容。 Firefox/Safari/Chrome 没有问题,因为您可以设置自定义拖动图像,但对于 IE,几乎没有其他选择。

在尝试大量事件排列后找到可行的解决方法。

在 IE mousemove 处理程序中清除选择似乎阻止了 dragStart 事件的触发。这(按照惯例)与其他浏览器的做法不一致。但是我发现,只要您不处理 iframe,清除 dragStart 处理程序中的选择就可以按预期工作。如果您正在处理 iframe,我认为 mousedown 是您可以处理的唯一可行事件。

然而,其他浏览器的行为也不尽如人意,因为在 dragstart 处理程序中清除选择似乎会阻止触发预期的 dragmove 事件。

解决方案是在所有 IE 浏览器的 dragstart 处理程序中处理选择清除,并在所有其他浏览器的 mousemove 处理程序中这样做。