悬停时jQuery拖放闪烁(仅限Webkit)

Eri*_*ric 6 jquery drag-and-drop

问题

我刚刚完成了一项功能,用户可以将文件拖到浏览器中,然后使用支持的文件上传插件来处理丢弃.

然而,为了给用户一个暗示他们甚至可以放弃东西的提示,我已经实现了一个dragover事件,以显示div类似于"Drop Here"的内容.反过来,这会隐藏div具有"选择文件..."按钮的按钮,并替换它,直到用户停止拖动.

但是,当我实现这一点时,拖动目标区域会导致闪烁.要明确:

  • div 显示"选择文件"界面.
  • 拖动项目(或拖动选定的文字); 显示"放在这里".
  • 项目拖过"Drop here"区域; 闪烁开始了.

另外:

  • Opera 12或Firefox 16中没有问题.
  • 这个问题在Chrome 23和Safari 5中显而易见.
  • 问题部分在于IE 9(IE 10未经测试); 它闪烁约5秒钟,然后停止.

的jsfiddle

(警告:小提琴很粗糙.)

只需选择一些文本并将其拖到蓝色框上,您就会看到会发生什么; 显而易见的是它不应该展示的行为.

用于小提琴的代码

var $dropTarget = $("#container");
$(document).bind("dragover", function(e) {
    if ($dropTarget.hasClass("highlight"))
        return;

    $dropTarget.addClass("highlight");
    $dropTarget.find("[name='drop']").show();
    $dropTarget.find("[name='drag']").hide();
}).bind("dragleave drop", function(e) {
    if (!$dropTarget.hasClass("highlight"))
        return;

    $dropTarget.removeClass("highlight");
    $dropTarget.find("[name='drop']").hide();
    $dropTarget.find("[name='drag']").show();
});?
Run Code Online (Sandbox Code Playgroud)

我的解决方案......?

说实话,我不知道该尝试什么.没有关于dragoveror 的行为的大量文档dragleave,我甚至不知道为什么会这样,所以我甚至无法开始调试它.我觉得dragover应该只开一次,但即使在屏幕上拖动也只是一遍又一遍地开火.

我看过谷歌图片和谷歌联系人的拖放行为,但他们的代码完全缩小,不可读,我甚至找不到任何指定的"拖动"行为.

那么,对这种看似奇怪的行为有什么解决方法吗?如果这是WebKit中的一个错误,我怀疑,是否有一些很好的解决方法和/或黑客我可以使用?

感谢大家的时间!

Eri*_*ric 18

经过一个多小时的淘洗,我找到了一个有类似问题的人.似乎Chrome和Safari(至少5)dragleave在进入子元素时会触发(似乎是在对该元素进行任何更改时,包括显示/隐藏的子项).

该解决方案是检查pageXpageY是等于0dragleave(但 drop).

var $dropTarget = $("#container");
$(document).bind("dragenter", function(e) {
    if (e.target == this) {
         return;
    }

    $dropTarget.addClass("highlight");
    $dropTarget.find("[name='drop']").show();
    $dropTarget.find("[name='drag']").hide();
}).bind("dragleave", function(e) {
    if (e.originalEvent.pageX != 0 || e.originalEvent.pageY != 0) {
        return false;
    }

    // Could use .trigger("drop") here.
    $dropTarget.removeClass("highlight");
    $dropTarget.find("[name='drop']").hide();
    $dropTarget.find("[name='drag']").show();
}).bind("drop", function(e) {
    $dropTarget.removeClass("highlight");
    $dropTarget.find("[name='drop']").hide();
    $dropTarget.find("[name='drag']").show();
});?
Run Code Online (Sandbox Code Playgroud)