rxjs6 でクリックとドラッグを識別する

rxjs6 でクリックとドラッグを識別する:


TL;DR

サンプルコード があるのでそれでだいたい分かると思う。


はじめに

同じ DOM に対して クリック処理とドラッグ処理をさせたいときってありますよね?

rxjs6 ならそこそこ楽に書けますよ。


実装

まずこちらの html と css を用意して

<div id="sample" /> 
#sample { 
  position: absolute; 
  top: 100px; 
  left: 100px; 
  width: 100px; 
  height: 100px; 
  background-color: #00a1e9; 
} 
#sample に対するクリックとドラッグの識別をやってみます。

具体的には ドラッグ開始クリック を識別します。それぞれ以下と定義します。

1. ドラッグ開始 … マウスが押されてから一定時間押しっぱなしであること

2. クリック … マウスが押されてから一定時間にマウスが離されること

上記処理の 早く発火した方 を拾うことができればいいわけです。

まず source のストリームを作ります。

1. 2. をそれぞれ of(e).pipe(delay(200))fromEvent(el, 'mouseup') と実装しています。

これらのストリームを merge して first で早く発火したほうを次へ流します。

最後に share で以降のドラッグとクリックの subscribe で同一のストリームを受け取るようにします。

const el = document.getElementById('sample') 
 
const source = fromEvent(el, 'mousedown').pipe( 
    switchMap((e) =>{ 
    // 200ms 遅延した mousedown イベント または 
    // mouseup イベントの 
    // どちらか早く発火した方を次へ流す 
    return merge( 
      of(e).pipe(delay(200)), 
      fromEvent(el, 'mouseup') 
    ).pipe(first()) 
  }), 
  share() 
) 
続いて subscribe の実装ですが、e.type === 'mouseup' でクリックかドラッグ開始か判別しています。

あとは煮るなり焼くなりしてみてください。

// e.type でクリックかドラッグか識別する 
const click = source.pipe( 
  filter((e) => e.type === 'mouseup') 
).subscribe((e) => { 
  alert('click!') 
}) 
 
const drag = source.pipe( 
  filter((e) => e.type !== 'mouseup') 
).subscribe((e) => { 
  alert('drag!') 
}) 


まとめ

楽ですね。

コメント

このブログの人気の投稿

投稿時間:2021-06-17 22:08:45 RSSフィード2021-06-17 22:00 分まとめ(2089件)

投稿時間:2021-06-20 02:06:12 RSSフィード2021-06-20 02:00 分まとめ(3871件)

投稿時間:2021-06-17 05:05:34 RSSフィード2021-06-17 05:00 分まとめ(1274件)