読み込み中...

JavaScriptでダブルクリックされた要素を判定する8つの方法

JavaScriptでダブルクリックを判定する JS
この記事は約18分で読めます。

【サイト内のコードはご自由に個人利用・商用利用いただけます】

この記事では、プログラムの基礎知識を前提に話を進めています。

説明のためのコードや、サンプルコードもありますので、もちろん初心者でも理解できるように表現してあります。

本記事のサンプルコードを活用して機能追加、目的を達成できるように作ってありますので、是非ご活用ください。

※この記事は、一般的にプロフェッショナルの指標とされる『実務経験10,000時間以上』を満たす現役のプログラマチームによって監修されています。

※Japanシーモアは、常に解説内容のわかりやすさや記事の品質に注力しております。不具合、分かりにくい説明や不適切な表現、動かないコードなど気になることがございましたら、記事の品質向上の為にお問い合わせフォームにてご共有いただけますと幸いです。
(送信された情報は、プライバシーポリシーのもと、厳正に取扱い、処分させていただきます。)

●ダブルクリックとは?

ダブルクリックってよく聞くけど、具体的にどういうことなんでしょうか?

実は、ダブルクリックには明確な定義があるんです。

一般的には、マウスの左ボタンを短い間隔で2回クリックすることをダブルクリックと呼びます。

○ダブルクリックの定義と判定基準

ダブルクリックの判定基準は、主に2つのパラメータで決まります。

1つ目は「クリック間隔」です。2回のクリックがどれだけ短い間隔で行われたかが重要なポイントになります。

多くのシステムでは、300ミリ秒以内に2回のクリックが行われた場合にダブルクリックと判定しています。

2つ目は「クリック位置」です。

2回のクリックが同じ場所、もしくは非常に近い位置で行われる必要があります。

これは、ユーザーが意図的に同じ場所をダブルクリックしたと判断するためです。

○シングルクリックとの違い

シングルクリックは、文字通り1回のクリックのことを指します。

一方、ダブルクリックは2回の連続したクリックです。

この2つは明確に区別されます。

シングルクリックは、要素の選択やボタンのクリックなど、一般的なユーザーアクションに使われます。

それに対し、ダブルクリックは特別な操作に割り当てられることが多いです。

例えば、ファイルやフォルダを開く、テキストを選択するなどの操作です。

○ダブルクリックを使うメリット

ではなぜ、わざわざダブルクリックを使うのでしょうか?

それは、ユーザビリティを向上させるためです。

シングルクリックは非常に一般的な操作なので、誤クリックが発生しやすいんです。

特に重要な操作をシングルクリックに割り当てると、ユーザーが意図せずその操作を実行してしまう可能性があります。

ダブルクリックを使えば、そういった誤操作を防げます。ダブルクリックは意図的に行われる操作なので、ユーザーが本当にその操作を実行したいときだけ反応するようにできるんです。

これにより、ユーザーエクスペリエンスを向上させることができます。

また、同じ操作に対してシングルクリックとダブルクリックを使い分けることで、操作性に深みを持たせることもできます。

例えば、ファイルの選択はシングルクリック、ファイルを開くのはダブルクリックというように、使い分けることで直感的な操作性を実現できるんです。

●JavaScriptでダブルクリックを検知する方法

さて、JavaScriptでダブルクリックを検知するにはどうすればいいのでしょうか?

実は、JavaScriptにはダブルクリックを直接検知するためのイベントが用意されているんです。

それが「dblclick」イベントです。

○サンプルコード1:dblclickイベントを使う

では早速、dblclickイベントを使ってダブルクリックを検知してみましょう。

下記のようなHTMLがあるとします。

<div id="myElement">ダブルクリックしてね</div>

このdiv要素をダブルクリックしたときに、アラートを表示するようにしてみます。

JavaScriptのコードはこんな感じです。

document.getElementById('myElement').addEventListener('dblclick', function() {
  alert('ダブルクリックされました!');
});

このコードでは、idが「myElement」の要素を取得し、その要素に対してdblclickイベントのリスナーを追加しています。

ダブルクリックが発生すると、アラートが表示されます。

実際に試してみると、「ダブルクリックしてね」というテキストをダブルクリックすると、「ダブルクリックされました!」というアラートが表示されるはずです。

これで、dblclickイベントを使ったダブルクリック検知ができました。

○サンプルコード2:クリック間隔を自分で計測する

ただ、dblclickイベントを使う方法には少し問題があります。

それは、ブラウザによってダブルクリックの判定基準が異なるということです。

つまり、ブラウザによっては少し間隔が長くてもダブルクリックと判定されたり、逆に厳しすぎてダブルクリックと判定されなかったりするんです。

そこで、クリック間隔を自分で計測して、ダブルクリックを判定する方法を見てみましょう。

下記のようなJavaScriptのコードを見てください。

let lastClickTime = 0;

document.getElementById('myElement').addEventListener('click', function() {
  const currentTime = new Date().getTime();
  if (currentTime - lastClickTime < 300) {
    alert('ダブルクリックされました!');
  }
  lastClickTime = currentTime;
});

このコードでは、クリックイベントのリスナーを追加しています。

クリックが発生すると、現在の時刻(ミリ秒)を取得し、前回のクリック時刻との差を計算します。

その差が300ミリ秒未満であれば、ダブルクリックとみなしてアラートを表示するという仕組みです。

実行結果は先ほどと同じで、素早く2回クリックすると「ダブルクリックされました!」というアラートが表示されます。

この方法なら、ブラウザに依存せずに一定の基準でダブルクリックを判定できます。

○どちらの方法を使うべき?

では、この2つの方法のどちらを使うべきでしょうか?

結論から言うと、状況に応じて使い分けるのが良いでしょう。

dblclickイベントを使う方法は、シンプルで直感的です。

特にダブルクリックの間隔にこだわりがない場合は、この方法で十分だと思います。

一方、クリック間隔を自分で計測する方法は、ダブルクリックの判定基準をカスタマイズできるのが大きなメリットです。

例えば、ゲームなどでは素早いダブルクリックを要求することがあります。

そんな場合は、判定基準を厳しくするために、この方法が適しているでしょう。

また、モバイルデバイスではdblclickイベントがサポートされていない場合があります。

そんなときにも、クリック間隔を計測する方法なら対応できます。

ということで、ダブルクリック検知の実装方法は、要件に合わせて柔軟に選択していくのが良いですね。

シンプルに実装したい場合はdblclickイベント、細かな制御が必要な場合はクリック間隔の計測と、使い分けていきましょう。

●ダブルクリックされた要素を特定する

ダブルクリックを検知できるようになったら、次はダブルクリックされた要素を特定したくなりますよね。

例えば、ダブルクリックされた画像を拡大表示したり、ダブルクリックされたテキストを編集可能にしたりといった具合です。

そのためには、どの要素がダブルクリックされたのかを知る必要があります。

JavaScriptにはそれを実現するための方法がいくつかあるんです。

早速見ていきましょう。

○サンプルコード3:event.targetを使う

1つ目の方法は、イベントオブジェクトのtargetプロパティを使うことです。

下記のようなHTMLがあるとします。

<div id="container">
  <p>段落1</p>
  <p>段落2</p>
  <p>段落3</p>
</div>

ここで、どのp要素がダブルクリックされたかを特定するには、次のようなJavaScriptのコードを書きます。

document.getElementById('container').addEventListener('dblclick', function(event) {
  console.log(event.target.textContent);
});

このコードでは、idが「container」の要素にdblclickイベントのリスナーを追加しています。

ダブルクリックが発生すると、イベントオブジェクトのtargetプロパティから、ダブルクリックされた要素を取得し、そのtextContentプロパティをコンソールに出力します。

実際に試してみると、例えば「段落2」をダブルクリックすると、コンソールに「段落2」と表示されるはずです。

このように、event.targetを使えば、ダブルクリックされた要素を簡単に特定できます。

○サンプルコード4:イベント委譲を使う

2つ目の方法は、イベント委譲を使う方法です。

イベント委譲とは、子要素で発生したイベントを親要素で捕捉する手法のことです。

先ほどのHTMLを使って説明しましょう。

document.getElementById('container').addEventListener('dblclick', function(event) {
  if (event.target.tagName === 'P') {
    console.log(event.target.textContent);
  }
});

このコードでは、containerにdblclickイベントのリスナーを追加しています。

ダブルクリックが発生すると、イベントオブジェクトのtargetプロパティをチェックします。

それがP要素であれば、そのtextContentプロパティをコンソールに出力するという仕組みです。

実行結果は先ほどと同じで、「段落2」をダブルクリックすればコンソールに「段落2」と表示されます。

このように、イベント委譲を使えば、親要素に1つイベントリスナーを追加するだけで、すべての子要素のイベントを処理できます。

○要素特定のポイント

ダブルクリックされた要素を特定する際には、次の2点がポイントになります。

1つ目は、イベントリスナーをどの要素に追加するかです。

できるだけ親要素に追加するのがおすすめです。そうすれば、イベント委譲の恩恵を受けられます。

たくさんの子要素に個別にイベントリスナーを追加するよりも効率的ですからね。

2つ目は、イベントオブジェクトのプロパティを上手に使うことです。

targetプロパティはダブルクリックされた要素そのものを指しますが、currentTargetプロパティはイベントリスナーが追加されている要素を指します。

この2つを適切に使い分けることが大切です。

また、ダブルクリックされた要素の種類に応じて処理を変えたい場合は、tagNameやclassNameなどのプロパティをチェックするのが有効です。

●よくあるエラーと注意点

ダブルクリック判定の実装は、一見簡単そうに見えて、実はいくつかの落とし穴があるんです。

実際に実装してみると、思わぬエラーに遭遇したり、ユーザビリティの問題に気づいたりすることがあります。

そこで、ここではダブルクリック判定の実装でよく遭遇するエラーと注意点を見ていきましょう。

これらを理解しておくことで、より堅牢で使いやすいダブルクリック処理を実現できるはずです。

○ダブルクリックとシングルクリックの競合

まず注意したいのが、ダブルクリックとシングルクリックの競合です。

例えば、あるボタンにシングルクリックとダブルクリックの両方のイベントリスナーを追加したとします。

<button id="myButton">クリックしてね</button>
const button = document.getElementById('myButton');

button.addEventListener('click', function() {
  console.log('シングルクリックされました');
});

button.addEventListener('dblclick', function() {
  console.log('ダブルクリックされました');
});

このコードでは、buttonをシングルクリックすると「シングルクリックされました」、ダブルクリックすると「ダブルクリックされました」とコンソールに出力されそうですね。

ところが、実際に試してみると、ダブルクリックしたときに「シングルクリックされました」も一緒に出力されてしまうんです。

これは、ダブルクリックがシングルクリックを2回含んでいるためです。

この問題を避けるためには、ダブルクリックイベントの中でイベントの伝播を止める必要があります。

button.addEventListener('dblclick', function(event) {
  event.preventDefault();
  console.log('ダブルクリックされました');
});

このように、event.preventDefault()を呼び出すことで、ダブルクリック時のシングルクリックイベントをキャンセルできます。

○モバイル端末での動作の違い

次に注意したいのが、モバイル端末でのダブルクリックの動作です。

実は、多くのモバイルブラウザではdblclickイベントがサポートされていないんです。

代わりに、タップイベントを使う必要があります。

例えば、ダブルタップを判定するには次のようなコードを書きます。

let lastTapTime = 0;

element.addEventListener('touchend', function(event) {
  const currentTime = new Date().getTime();
  if (currentTime - lastTapTime < 300) {
    console.log('ダブルタップされました');
  }
  lastTapTime = currentTime;
});

このコードでは、touchendイベントを使ってタップを検知し、前回のタップとの時間差から、300ミリ秒以内の連続タップをダブルタップとみなしています。

○過剰な判定間隔の設定

最後に、ダブルクリックの判定間隔の設定についてお話ししましょう。

先ほどのサンプルコードでは、300ミリ秒という値を使いましたが、この値が大きすぎると問題になることがあります。

例えば、判定間隔を1秒にしたとします。

let lastClickTime = 0;

element.addEventListener('click', function() {
  const currentTime = new Date().getTime();
  if (currentTime - lastClickTime < 1000) {
    console.log('ダブルクリックされました');
  }
  lastClickTime = currentTime;
});

この場合、1秒以内の2回のクリックがダブルクリックとして判定されます。しかし、これでは少し間隔が長すぎますよね。

ユーザーは、もっと短い間隔でダブルクリックするのが一般的です。

判定間隔を長くしすぎると、意図せずダブルクリックが発生したり、逆に意図したダブルクリックが認識されなかったりと、ユーザビリティの問題につながります。

一般的には、300ミリ秒から500ミリ秒程度が適切だと言われています。

ただ、適切な判定間隔は状況によって異なります。

例えば、ゲームなどの反応速度が重要なアプリケーションでは、もっと短い間隔が求められるかもしれません。

逆に、高齢者向けのサイトでは、もう少し長めの間隔が適切かもしれません。

大切なのは、ユーザーの期待に合わせて判定間隔を設定することです。

サイトやアプリケーションの用途や対象ユーザーをよく考え、最適な値を見つけていきましょう。

●ダブルクリック判定の応用例

さて、ここまでダブルクリックを検知する方法と、ダブルクリックされた要素を特定する方法を見てきました。

じゃあ実際に、それらの技術をどう活用すればいいのでしょうか?

実は、ダブルクリックは様々な場面で使われているんです。

ここでは、具体的な応用例をいくつか見ていきましょう。

きっと、ダブルクリックの可能性の広さに驚くはずです。

○サンプルコード5:要素の表示/非表示の切り替え

まずは、要素の表示/非表示の切り替えです。

例えば、ダブルクリックするとその要素が消えたり、逆に現れたりするようなインターフェースを作れます。

<div id="box">ダブルクリックで消えるよ!</div>
const box = document.getElementById('box');

box.addEventListener('dblclick', function() {
  this.style.display = 'none';
});

このコードでは、idが「box」のdiv要素をダブルクリックすると、そのdisplayプロパティが「none」になり、要素が非表示になります。

逆に、非表示の要素をダブルクリックで表示させることもできます。

<button id="showButton">ダブルクリックで箱を表示</button>
<div id="box" style="display: none;">こんにちは!</div>
const showButton = document.getElementById('showButton');
const box = document.getElementById('box');

showButton.addEventListener('dblclick', function() {
  box.style.display = 'block';
});

この例では、ボタンをダブルクリックすると、非表示のdiv要素が表示されます。

このように、ダブルクリックを使って要素の表示状態を切り替えることができるんです。

○サンプルコード6:ダブルクリックによる画像拡大

次は、画像の拡大です。

サムネイル画像をダブルクリックすると、拡大表示されるようなインターフェースを作ってみましょう。

<img id="thumbnail" src="image.jpg" alt="サムネイル画像">
<div id="fullImage" style="display: none;">
  <img src="image.jpg" alt="拡大画像">
</div>
const thumbnail = document.getElementById('thumbnail');
const fullImage = document.getElementById('fullImage');

thumbnail.addEventListener('dblclick', function() {
  fullImage.style.display = 'block';
});

fullImage.addEventListener('click', function() {
  this.style.display = 'none';
});

このコードでは、サムネイル画像(thumbnail)をダブルクリックすると、拡大画像(fullImage)が表示されます。

拡大画像をクリックすると、再び非表示になります。

このように、ダブルクリックを使って画像を拡大表示するインターフェースを作ることができます。

写真ギャラリーやECサイトの商品画像などで使えそうですね。

○サンプルコード7:地図のダブルクリックズーム

3つ目の例は、地図のダブルクリックズームです。

Google Mapsなどを使っていると、地図をダブルクリックするとその地点にズームインするという動作をよく見かけますよね。

これは、Google Maps APIを使って実現できます。

<div id="map" style="height: 400px; width: 100%;"></div>
function initMap() {
  const map = new google.maps.Map(document.getElementById('map'), {
    center: { lat: 35.681236, lng: 139.767125 },
    zoom: 12
  });

  map.addListener('dblclick', function(event) {
    map.setCenter(event.latLng);
    map.setZoom(map.getZoom() + 1);
  });
}

このコードでは、まず初期状態の地図を表示しています。

そして、地図上でダブルクリックイベントが発生したら、そのクリック位置に地図の中心を移動し、ズームレベルを1上げるという処理をしています。

Google Maps APIの詳細はここでは割愛しますが、ダブルクリックイベントを活用することで、このような地図のインターラクションを実装できるんです。

○サンプルコード8:テキスト選択の無効化

最後に、ダブルクリックを使ったテキスト選択の無効化について見てみましょう。

例えば、ダブルクリックされたテキストは選択できないようにしたいという場合です。

<p id="text">このテキストはダブルクリックしても選択できません。</p>
const text = document.getElementById('text');

text.addEventListener('dblclick', function(event) {
  event.preventDefault();
});

このコードでは、pタグ内のテキストをダブルクリックしてもテキスト選択ができないようにしています。

ポイントは、イベントオブジェクトのpreventDefault()メソッドを呼び出すことです。

これにより、ダブルクリック時のデフォルトの動作(テキスト選択)がキャンセルされます。

ただ、ユーザビリティの観点からは、テキスト選択を無効化するのは慎重に検討する必要がありますね。

ユーザーの利便性を損なわないよう、無効化する範囲は最小限にとどめるべきでしょう。

まとめ

ダブルクリック判定は、要素の表示/非表示の切り替え、画像の拡大表示、地図のズーム、テキスト選択の制御など、様々な場面で活用できます。

適切な場面で適度に使うことで、ウェブサイトやアプリケーションのインタラクティブ性を高め、ユーザーの利便性や満足度の向上につなげることができるでしょう。

このガイドを参考に、みなさんのウェブサイトやアプリケーションでダブルクリックを活用したインターフェースを実装してみてください。

より洗練されたインターフェースを作っていきましょう。