在窗口外拖动时如何检测Firefox中的dragleave事件 [javascript]


Answers

根据您希望完成的事情,您可以使用:-moz-drag-over伪类来解决此问题,该类仅在Firefox中提供,它允许您对被拖到元素上的文件作出反应。

看看这个简单的演示http://codepen.io/ryanseddon/pen/Ccsua

.dragover {
    background: red;
    width: 500px;
    height: 300px;
}
.dragover:-moz-drag-over {
    background: green;
}
Question

在窗口外拖动时,Firefox不能正确地触发dragleave事件:

https://bugzilla.mozilla.org/show_bug.cgi?id=665704

https://bugzilla.mozilla.org/show_bug.cgi?id=656164

我正在尝试为此开发一个解决方法(我知道这是可能的,因为Gmail正在这样做),但我唯一能想出的东西似乎真的很黑。

有一种方法可以知道在窗外拖动时是否等待dragover事件停止发射(因为dragover在拖放操作过程中不断发射)。 以下是我如何做到这一点:

var timeout;

function dragleaveFunctionality() {
  // do stuff
}

function firefoxTimeoutHack() {
  clearTimeout(timeout);
  timeout = setTimeout(dragleaveFunctionality, 200);
}

$(document).on('dragover', firefoxTimeoutHack);

这个代码本质上是一遍又一遍地创建和清除一个超时。 除非dragover事件停止发射,否则将不会达到200毫秒超时。

虽然这有效,但我不喜欢为此使用超时的想法。 感觉不对 这也意味着在“dropzone”造型消失之前还有一点点滞后。

我的另一个想法是检测鼠标何时离开窗口,但是正常的做法似乎在拖放操作中不起作用。

有没有人有更好的方式做到这一点?

更新:

这里是我使用的代码:

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <title>Drag and Drop Issue</title>
  <script src="http://code.jquery.com/jquery.js"></script>
</head>
<body>
  Open up the console and look at what number is reporting when dragging files in and out of the window. The number should always be 0 when leaving the window, but in Firefox it's not.
  <script type="text/javascript">
    $(function() {
      var counter = 0;
      $(document).on('dragenter', function(e) {
        counter += 1;
        console.log(counter, e.target);
      });
      $(document).on('dragleave', function(e) {
        counter -= 1;
        console.log(counter, e.target);
      });
    });
  </script>  
</body>
</html>



受@PhilipWalton代码的启发,我简化了jQuery插件代码。

$.fn.draghover = function(fnIn, fnOut) {
    return this.each(function() {
        var n = 0;
        $(this).on('dragenter', function(e) {
            (++n, n==1) && fnIn && fnIn.call(this, e);
        }).on('dragleave drop', function(e) {
            (--n, n==0) && fnOut && fnOut.call(this, e);
        });
    });
};

现在你可以像jquery hover方法一样使用jquery插件:

// Testing code 1
$(window).draghover(function() {
    console.log('into window');
}, function() {
    console.log('out of window');
});

// Testing code 2
$('#d1').draghover(function() {
    console.log('into #d1');
}, function() {
    console.log('out of #d1');
});