跨浏览器拖动前清除内容选择的方法
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 处理程序中这样做。
一直在尝试解决在执行 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 处理程序中这样做。