Skip to main content

目的

「ボタン」の実装とひとえに言っても何パターンか存在する。それに拠って生じる諸問題に対して実装と動作サンプルを両方提示することで考える時間を短くしたい。

目指す世界

  • 他者と実装仕様を策定する上で実際に触れる形式で認識を合わせることが最も効率が良い。
  • 実装のパターンに名前がついていたほうがわかりやすく、認識のズレが発生しにくい。
  • 実装サンプルが付いていることにより実装者が工数見積をしやすくなる。
  • 想定されるユースケースをある程度例示しておくことで実装者と仕様策定者が別れている場合でも円滑に建設的な意見が言える状態を作れる。

(と信じてる)

実装と動作サンプル

実装はGitHubでも公開しています。

用語定義

用語意味
クリックアクション/アクションクリックそのもの。フォーカスを当てると Enter Key でも再現できる場合がある
クリックイベント/イベントクリックアクションに紐付いて発生する処理

ボタンの振る舞いによる分類

Default Pattern

Source Code

振る舞いの特徴

  • ボタンに対するクリックアクションの回数だけ紐づくアクションが発生する。
  • クリックイベントがブラウザ(クライアント)内に閉じて自身以外に迷惑をかけないような UI に対して有効

実装の特徴

  • button要素にそのままクリックイベントをマッピングした実装
  • すべてのクリックアクションと紐づくイベントを許容する

考えるべきこと

  • 連打された場合にアクションを受ける対象が負荷や表示に問題がないか確認する。
    • アクションが API に紐付いている場合、タブでフォーカスして Enter Key を押されると DDoS のような振る舞いをする。

ユースケース

  • 動画のコントローラー
    • 再生/停止
  • ボリューム
    • -1/+1 などの細かい調整ボタン

Blocking Pattern

Source Code

振る舞いの特徴

  • ボタンをクリックすると自身に対するクリックアクションが無効化(disable)される
  • 何かしらの条件で disable が解除する
  • disable を解除する条件がない場合もある
  • システムが意図しないユーザーのクリックアクションを防ぐことができる

実装の特徴

  • button要素に対してdisable属性を渡す

考えるべきこと

  • ボタンをクリックした後に disable になるような振る舞いがユーザーにとってストレスにならないか確認する
  • disable を解除するような動作が必要な場合、解除するための導線が適切か考える必要がある

ユースケース

  • フォームの送信ボタン
  • リロードボタン

Debounce Pattern

Source Code

振る舞いの特徴

  • クリックアクションを実行後、指定時間だけ遅延してクリックイベントが発生する。指定時間より短い時間にクリックした場合、前回のクリックアクションに紐づくイベントはキャンセルされ、最新のクリックイベントの発生を待機する。
  • ボタンが disable に変化しない
  • クリックイベントを間引く実装
  • 連打し続けた場合、最後のクリックアクションに紐づくイベントしか発生しない

実装の特徴

  • setTimeout を利用して、クリックイベントとクリックアクションを非同期的に扱う

考えるべきこと

  • ボタンの UI が変化しないと不具合と感じられる可能性がある

ユースケース

  • フォロー/アンフォローをトグルボタンとして実装し、一番最後の結果を送信するようなケース
    • 花びらをちぎって一番最後の結果を信じるようなイメージ
  • 「メール送信」などのボタン
    • 押した後に間違いに気がついてキャンセルしたいような場合
  • (長押しの例だが)Facebook Messanger の"いいね"ボタンのようにボタンの押下時間(クリック数)に応じて UI が変化する要な場合

Throttle Pattern

Source Code

振る舞いの特徴

  • クリックアクションを実行後、指定時間だけ遅延してクリックイベントが発生する。指定時間より短い時間にクリックした場合、現在のクリックアクションに紐づくイベントはキャンセルされ、前回のクリックイベントの発生を待機する。
  • ボタンが disable に変化しない
  • クリックイベントを間引く実装
  • 連打し続けた場合、指定時間の感覚でイベントが発生する

実装の特徴

  • setTimeout を利用して、クリックイベントとクリックアクションを非同期的に扱う

考えるべきこと

  • ボタンの UI が変化しないと不具合と感じられる可能性がある

ユースケース

  • イベントが API Request を発生させるような場合に、Request の負荷を下げつつ、連打アクションの体験を提供するような場合
    • イベント発生時に受け入れたアクション数をまとめて送信するようなケース

Transition Pattern

Source Code

振る舞いの特徴

  • ボタンをクリックしたとき、別の UI が表示される
  • ボタンをクリックしたとき、ページに遷移する
  • ボタンをクリックしたときに、ボタン自体が別の場所に移動する、もしくは隠れる
  • ボタン以外の UI によって、ボタンのクリックアクション自体が防がれる
  • disable にしてもしなくても良い
  • クリックの連打がそもそもできない状態になる

実装の特徴

  • ボタンに対して別の UI をかぶせる
  • 画面を遷移させる

考えるべきこと

  • テーブル表示されるような UI で 1 行ごとにボタンが設置されているような場合に向かない
    • クリックのたびに遷移したり、キャンセルが出来ないような UI はストレスが溜まる
      • Debounce Pattern をおすすめしたい
  • (上記より)大量な情報を操作するような場面に向かない

ユースケース

  • フォーム入力の確定ボタン。確定後に画面遷移させるような場面
  • 確認が必要な情報を操作するときのボタン