拖动文本时,Firefox会触发dragleave
我试图追踪整个屏幕的dragenter / leave,到目前为止Chrome / Safari的工作状况良好,可以从https://stackoverflow.com/a/10310815/698289的draghover插件中获得,如下所示:
$.fn.draghover = function(options) {
return this.each(function() {
var collection = $(),
self = $(this);
self.on('dragenter', function(e) {
if (collection.size() === 0) {
self.trigger('draghoverstart');
}
collection = collection.add(e.target);
});
self.on('dragleave drop', function(e) {
// timeout is needed because Firefox 3.6 fires the dragleave event on
// the previous element before firing dragenter on the next one
setTimeout( function() {
collection = collection.not(e.target);
if (collection.size() === 0) {
self.trigger('draghoverend');
}
}, 1);
});
});
};
function setText(text) {
$('p.target').text(text);
}
$(document).ready(function() {
$(window).draghover().on({
'draghoverstart': function() {
setText('enter');
},
'draghoverend': function() {
setText('leave');
}
});
});
然而,当我拖动文本项目时,Firefox仍然给我带来麻烦,下面是一个小提示:http://jsfiddle.net/tusRy/6/
这是一个Firefox的错误,或者这可以驯服JS? 还是有更强大的方法来执行所有这些?
谢谢!
更新:更新小提琴http://jsfiddle.net/tusRy/6/以减少混乱一点。 解释小提琴的预期行为:
在Firefox中,当您将文件拖到文本上时,会触发LEAVE事件。
从版本22.0开始,Firefox仍在执行此操作。 当您拖动文本节点时,它会触发两种dragenter
和dragleave
事件:一种是事件目标和relatedTarget是文本节点的父元素,另一种是目标是父元素,另一种是relatedTarget是实际文本节点(甚至没有适当的DOM元素)。
解决方法是检查dragenter
和dragleave
处理程序中的这两种事件,并忽略它们:
try {
if(event.relatedTarget.nodeType == 3) return;
} catch(err) {}
if(event.target === event.relatedTarget) return;
我使用try / catch块来检查nodeType,因为偶尔事件从文档外部(例如在其他iframe中)触发(莫名其妙地)并试图访问它们的nodeType会引发权限错误。
这是实现:http://jsfiddle.net/9A7te/
我提出了一种解决方案,但在Chrome和FF以外的其他浏览器上进行测试,但目前仍在运行。 这就是setTimeout
现在的样子:
setTimeout( function() {
var isChild = false;
// in order to get permission errors, use the try-catch
// to check if the relatedTarget is a child of the body
try {
isChild = $('body').find(e.relatedTarget).length ? true : isChild;
}
catch(err){} // do nothing
collection = collection.not(e.target);
if (collection.size() === 0 && !isChild) {
self.trigger('draghoverend');
}
}, 1);
整个代码在这里 - http://jsfiddle.net/tusRy/13/。
这个想法是检查相关标签是否是身体的一个孩子,在这种情况下,我们仍然在浏览器中,并且不应触发draghoverend
事件。 由于这会在移出窗口时抛出错误,我使用了一种尝试方法来避免它。
那么,也许有更多JS技能的人可以改善这一点:)
1)你的dropzone应该只有一个子元素,它可能有你需要的一切。 就像是
<div id="#dropzone">
<div><!--Your contents here--></div>
</div>
2)使用这个CSS:
#dropzone * { pointer-events: none; }
您可能需要在*
:before
和:after
包含:before
*
因为不适用于它们。
这应该足以让Firefox和Chrome的下载工作。 在你的例子中,它应该足以添加:
body * { pointer-events: none; }
在CSS的末尾。 我在这里完成了:
其他例子:
上一篇: Firefox firing dragleave when dragging over text
下一篇: Firefox won't play .WAV files using the HTML5 <audio> tag?