React-dnd: Firefox丢失事件的问题

创建于 2018-04-05  ·  7评论  ·  资料来源: react-dnd/react-dnd

我发现了一个非常讨厌的错误,似乎在Firefox本身中绊倒了一个问题。 即使在国际象棋教程示例中,我也可以重现此错误。 基本上,您可以进入一种状态,即Firefox除了dragstart之外不会发送任何鼠标事件。

重现

单击拖动源并开始拖动,在显示预览之前释放鼠标。 在本教程示例中,执行一次后,放置目标将保持突出显示。 有时您必须立即再次执行操作以触发完整的错误。

在较慢的页面(预览需要一段时间才能显示)上,这更容易实现。 我的页面非常慢,我可以通过在单击开始拖动后甚至一秒钟的时间内释放单击来重现它。

病征

触发该错误后,Firefox似乎停止向draggingstart以外的几乎所有选项卡发送拖动事件。 有时,我可以在页面上用react-dnd引起问题,然后所有其他选项卡开始表现出相同的症状。

只有两种方法可以使自己摆脱这种破碎状态。 首先,您可以关闭然后重新打开浏览器。 其次,可以在仍在运行react-dnd的页面上启动拖动。 完成此操作后,导致中断的页面将收到一个dragend事件。 所以:

  1. 标签1看到了clickstart
  2. 标签1除了clickstart之外,没有其他事件
  3. 打开选项卡2并开始拖动
  4. 标签1看到了clickend,现在可以再次使用

这是一个使用两个标签显示https://react-dnd.github.io/react-dnd/examples-chessboard-tutorial-app.html的选项卡的视频,显示了这种奇怪的行为

ReactDnDFirefoxBug.zip

我在使用Firefox 59.0.2(64位)的macOS High Sierra 10.13.3(17D102)上。 它似乎发生在> = 57的任何版本上。我已经用react-dnd 2.6.0和2.5.4重现了该错误。

我很乐意为您进行任何测试或调试,以解决此问题,或者解决此问题的方法,如果问题出在Firefox本身。

browser bug bug wontfix

最有用的评论

在此处通过Mozilla打开的票证: https :

所有7条评论

我发现了一种更好的方法来触发甚至不使用react-dnd的错误。

破坏页面后,我发现要解决的唯一方法是在“ react-dnd”示例上移动棋子,或重新启动Firefox。 我不确定用react-dnd这个例子到底在做什么,或者不确定如何解决这个问题。

<html>
<head>
</head>
<body>
<p>
  Click and drag the draggable item for longer than 1 second to see it dragging.
  Click, drag, and release within 1 second to cause the error.
</p>

<div class="dropzone">
  <div id="draggable" draggable="true" ondragstart="event.dataTransfer.setData('text/plain',null)">
    This div is draggable
  </div>
</div>
<div class="dropzone"></div>
<div class="dropzone"></div>
<div class="dropzone"></div>

<style>
  #draggable {
    width: 200px;
    height: 20px;
    text-align: center;
    background: white;
  }

  .dropzone {
    width: 200px;
    height: 20px;
    background: blueviolet;
    margin-bottom: 10px;
    padding: 10px;
  }
</style>

<script>
  var dragged;

  /* events fired on the draggable target */
  document.addEventListener("drag", function( event ) {
    console.log('drag')
  }, false);

  function sleep(ms){
      var waitTimeInMilliseconds = new Date().getTime() + ms;
      while(new Date().getTime() < waitTimeInMilliseconds ) true;
  }

  document.addEventListener("dragstart", function( event ) {
      // store a ref. on the dragged elem
      dragged = event.target;
      // make it half transparent
      event.target.style.opacity = .5;

      sleep(1000);

      // You can use this approach instead of the sleep. The image is quite
      // large so it's easy to release the mouse before the image is loaded
      // var img = new Image();
      // img.src = 'http://awakeningthegoddesswithin.net/wp/wp-content/uploads/2015/06/moon.jpg';
      // event.dataTransfer.setDragImage(img, 10, 10);
  }, false);

  document.addEventListener("dragend", function( event ) {
    console.log("dragend")
      // reset the transparency
      event.target.style.opacity = "";
  }, false);

  /* events fired on the drop targets */
  document.addEventListener("dragover", function( event ) {
      console.log("dragover")
      // prevent default to allow drop
      event.preventDefault();
  }, false);

  document.addEventListener("dragenter", function( event ) {
      console.log("dragenter")
      // highlight potential drop target when the draggable element enters it
      if ( event.target.className == "dropzone" ) {
          event.target.style.background = "purple";
      }

  }, false);

  document.addEventListener("dragleave", function( event ) {
      console.log("dragleave")
      // reset background of potential drop target when the draggable element leaves it
      if ( event.target.className == "dropzone" ) {
          event.target.style.background = "";
      }

  }, false);

  document.addEventListener("drop", function( event ) {
      console.log("drop")
      // prevent default action (open as link for some elements)
      event.preventDefault();
      // move dragged elem to the selected drop target
      if ( event.target.className == "dropzone" ) {
          event.target.style.background = "";
          dragged.parentNode.removeChild( dragged );
          event.target.appendChild( dragged );
      }
  }, false);
</script>
</body>

在此处通过Mozilla打开的票证: https :

我可以确认这一点:(

已确认

Firefox已提交修复程序,应与Firefox 63一起发布(计划于2018-10-23发行)

由于此问题最近没有活动,因此已被自动标记为陈旧。 如果没有进一步的活动,它将关闭。 感谢您的贡献。

在Fedora 30和Windows 10(Firefox 69)下,这仍然在我身上发生。 我还将此信息添加到了Firefox票证中。 自从我对票证的最后评论是:

仅在“在主线程中”请求重绘时,该问题似乎也正在发生。
将重绘包装在requestAnimationFrame()中时,这可以按预期工作。

我们有什么办法可以解决库中的错误?

编辑09/19/2019:
Firefox 69中似乎出现了回归,重新引入了此错误,我已经向他们提交了新票证: https : =1582401

此页面是否有帮助?
0 / 5 - 0 等级