2017-03-11 13 views
3

シャドウ要素に内部的にイベントハンドラを付けています(私はイベントをユーザに伝播していません)、dragoverイベントを処理しています。私はイベントをデバウンスしようとするまで、すべてうまく動作します。 setTimeoutを使用すると、イベントが発生したように(イベントターゲットは)<my-element>のようにイベントが変更されたようです。どのようにシャドウDOMイベントをデバウンス/スロットルしますか?

これをより明確にするには、 <my-element>には、いくつかの要素を含むshadow domがあります。 setTimeoutを指定しないと、シャドウ要素の1つでイベントが正常に発生します。たとえば、<my-element>のシャドウドームの<li>または<button>です。 setTimeoutでイベントのデバウンスを試みるとすぐに、イベントターゲットは<my-element>に変更されます。

私の質問です。あなたはどのように影のDOMイベントをデバウンスできますか?

HTML

<html> 
    <head></head> 
    <body> 
     <my-element> 
      #shadow-root (open) 
       <ul> 
        <li draggable="true"> 
         <button>Hi</button> 
        </li> 
        <li draggable="true"> 
         <button>Hi</button> 
        </li> 
       </ul> 
       <ul class="drop-target"> 
       </ul> 
     </my-element> 
    </body> 
</html> 

Javascriptを:

//...class code 
    attachEventHandler(){ 
     let self = this; 

     self.shadowElement.addEventListener('dragover', (function debouncedDragOverFactory(){ 
      let timeoutId = 0, 
       evObj; 

      return function debouncedDragOver(ev){ 
       evObj = ev; //Only tracking the last event 
       if(!timeoutId){ 
        timeoutId = setTimeout(function(){ 
         self.onDragOver(evObj); //self is 'this' pointer of the class this code is in. 
               //onDragOver handles the drag event, obvisouly. 
         timeoutId = 0; 
        }, 100); 
       } 
      }; 
     })()); 
    } 

[更新]
はここPlunker exampleです。

2番目のイベントハンドラのsetTimeoutに1秒の遅延を付けました。だから'DIV'のノード名がスクロールし、ノード名が'LIST-EXAMPLE'であることがわかります。

divはshadowRootにあります。

LIST-EXAMPLEは、ウィンドウスコープイベントでユーザーに表示されるものです。

イベントの変化を回避するには、3番目のイベントハンドラで、必要なデータをコピーします。

+0

私は 'のsetTimeout()は' window' 'にバインドされたデフォルトですが、私は信じています暗い地下世界に十分に精通していないため、それが理由です。 – zer00ne

+0

それも私の推測でした。私はシャドウ・ルート上に別のウィンドウ・コンテキストがあるかどうかを確認するために遊んでいます...おそらくそうではありません。 私は必要なイベントからデータを取得し、それを渡すだけだと思います。 – Jerinaw

+0

あなたの所見を投稿すると、私は不思議です。 – zer00ne

答えて

2

私の更新では私自身の質問にお答えします。

ここにはPlunker exampleがあります。

2番目のイベントハンドラのsetTimeoutに1秒の遅延を設定します。したがって、 'DIV'ノード名の束が次に 'LIST-EXAMPLE'ノード名までスクロールして表示されます。

divはshadowRootにあります。

LIST-EXAMPLEは、ウィンドウスコープイベントでユーザーに表示されるものです。

イベントの変化を回避するには、3番目のイベントハンドラで、必要なデータをコピーします。

通常はデバウンスすることはできますが、イベントから必要なデータをコピーして、ワーカー機能でそのコピーを使用するようにしてください。

可能性のあるソリューションで上からコードを更新するには...

//...class code 
attachEventHandler(){ 
    let self = this; 

    self.shadowElement.addEventListener('dragover', (function debouncedDragOverFactory(){ 
     let timeoutId = 0, 
      evTarget; 

     return function debouncedDragOver(ev){ 
      evTarget = ev.target; //Copy the data off that I need 
      if(!timeoutId){ 
       timeoutId = setTimeout(function(){ 
        self.onDragOver(evTarget); 
        timeoutId = 0; 
       }, 100); 
      } 
     }; 
    })()); 
} 
1

またsetTimeout関数の3番目のパラメータとして必要なデータを渡すことができます:

li.addEventListener('dragover', function(e){ 
    setTimeout(function(nodeName){ 
     output.textContent = '3' + nodeName + '\n' + output.textContent;  
    }, 2000, e.target.nodeName); 
}); 
関連する問題