React-dnd: Firefoxがイベントを失う問題

作成日 2018年04月05日  ·  7コメント  ·  ソース: react-dnd/react-dnd

Firefox自体で問題が発生しているように見えるかなり厄介なバグを見つけました。 チェスのチュートリアルの例でも、このエラーを再現できます。 基本的に、Firefoxがドラッグスタート以外のマウスイベントを送信していないように見える状態になる可能性があります。

再現

ドラッグソースをクリックしてドラッグを開始し、プレビューが表示される前にマウスを放します。 チュートリアルの例では、一度実行すると、ドロップターゲットは強調表示されたままになります。 完全なバグをトリガーするために、すぐにもう一度実行しなければならない場合があります。

これは、プレビューが表示されるまでに時間がかかる低速のページで実行するのがはるかに簡単です。 非常に遅いページがあり、ドラッグを開始してから1秒後でもクリックを離すことで再現できます。

症状

バグをトリガーすると、Firefoxはドラッグスタート以外のドラッグイベントをほぼすべてのタブに送信しなくなったように見えます。 時々、react-dndを使用して1ページで問題を引き起こすことがあり、その後、他のすべてのタブで同じ症状が現れ始めます。

この壊れた状態から抜け出すには2つの方法しかありません。 まず、ブラウザを閉じてから再度開くことができます。 次に、react-dndがまだ機能しているページでドラッグを開始できます。 これを行うと、中断の原因となったページがドラッグエンドイベントを受け取ります。 そう:

  1. タブ1にクリックスタートが表示されます
  2. タブ1には、クリックスタート以外のイベントは表示されません
  3. タブ2を開き、ドラッグを開始します
  4. タブ1にクリックエンドが表示され、再び機能しています

これは、 https: //react-dnd.github.io/react-dnd/examples-chessboard-tutorial-app.htmlを示す2つのタブを使用してこの奇妙な動作を示すビデオ

ReactDnDFirefoxBug.zip

Firefox 59.0.2(64ビット)を搭載したmacOS High Sierra 10.13.3(17D102)を使用しています。 57以上のバージョンで発生するようです。react-dnd2.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にリリース予定)

この問題は、最近のアクティビティがないため、自動的に古いものとしてマークされています。 それ以上のアクティビティが発生しない場合は閉じられます。 貢献していただきありがとうございます。

これは、Fedora30とWindows10(Firefox 69)の両方でまだ発生しています。 この情報をFirefoxのチケットにも追加しました。 私の前のチケットの最後のコメントから:

この問題は、「メインスレッドで」再描画が要求された場合にのみ発生しているようです。
再描画をrequestAnimationFrame()でラップすると、これは期待どおりに機能します。

ライブラリのバグを回避するためにできることはありますか?

2019年9月19日編集:
このバグを再導入するFirefox69でリグレッションが発生したようです、私は彼らに新しいチケットを提出しました: https

このページは役に立ちましたか?
0 / 5 - 0 評価