4
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

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

Posted at

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!')
})

まとめ

楽ですね。

4
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?