第2章-3節: JavaScriptでもっとすごいツールチップを!
前のページでは、HTMLとCSSだけで基本的なツールチップが作れることを見たね。シンプルで手軽だけど、もっと複雑なことをしようとすると、CSSだけではちょっと限界が見えてくるんだ。
そこで登場するのが、ウェブページに動きや対話性を加えるプログラミング言語、JavaScriptだ! JavaScriptを使うと、ツールチップはもっと賢く、もっと便利になるよ。どんなことができるようになるのか、一緒に探っていこう!
🚀 なぜJavaScriptを使うの? CSSだけじゃダメ?
CSSの:hover
で作るツールチップは手軽だけど、例えばこんなことは苦手なんだ。
- ツールチップの内容を、マウスを乗せた要素によってガラッと変えたい(例えば、商品のIDから詳しい情報をデータベースから取ってきて表示する、みたいなこと)。
- マウスカーソルの動きに合わせて、ツールチップがフワフワと追いかけてくるようにしたい。
- ツールチップの表示・非表示のタイミングを細かく制御したい(例えば、少し遅れて表示させたり)。
- スマートフォンなど、マウスホバーがないタッチデバイスでもツールチップを使いたい(例えばクリックで表示)。
- ツールチップが画面の端からはみ出さないように、自動で位置を調整したい。
JavaScriptを使えば、これらの「もっとこうしたい!」という願いを叶えることができるんだ。プログラムで細かく動きを制御できるから、表現の幅がグンと広がるよ!
📜 JavaScriptでツールチップを作る基本的な流れ
JavaScriptでツールチップを作る基本的なステップはこんな感じだ。
- HTMLの準備:
- ツールチップを表示させたい要素(トリガー要素)を用意する。これには、目印となる
class
名や、ツールチップの内容を保持するためのdata-*
属性を付けておくと便利だよ。
- ツールチップ本体となる要素をHTMLにあらかじめ用意しておくか、JavaScriptで動的に作り出す。今回は、あらかじめHTMLに一つだけ用意しておく方法を見てみよう。
- CSSの準備:
- ツールチップ本体の基本的な見た目(背景色、文字色、パディングなど)や、初期状態(最初は非表示にしておくなど)はCSSでスタイルを定義しておく。
- JavaScriptの処理:
- 要素の取得: トリガー要素やツールチップ本体の要素をJavaScriptで取得する。
- イベントリスナーの設定: トリガー要素にマウスが乗った時 (
mouseover
)、離れた時 (mouseout
)、動いた時 (mousemove
) などの「イベント」を監視する仕組み(イベントリスナー)を設定する。
- ツールチップの表示処理:
- トリガー要素からツールチップに表示したい内容(例えば
data-tooltip
属性の値)を取得する。
- ツールチップ本体の要素に、その内容を書き込む。
- ツールチップ本体の要素の位置を調整する(例えば、マウスカーソルの近く)。
- ツールチップ本体の要素を表示状態にする(CSSのクラスを付けたり、スタイルを直接変更したり)。
- ツールチップの非表示処理:
なんだか難しそうに聞こえるかもしれないけど、一つ一つの部品はそんなに複雑じゃないんだ。順番に見ていこう!
🛠️ 実装してみよう!JavaScriptツールチップ
ここでは、マウスを乗せるとその要素のdata-tooltip
属性に書かれた内容が表示され、マウスカーソルに少し遅れてついてくるツールチップを作ってみるよ。
1. HTMLの準備
まず、ツールチップを表示するための「箱」を一つだけHTMLのどこか(通常は<body>
の直下など)に用意しておく。この箱は普段は隠しておいて、JavaScriptが必要な時に表示するんだ。
<!-- ツールチップ本体 (最初は非表示) -->
<div id="js-tooltip"></div>
<!-- トリガーとなる要素の例 -->
<p>
ここにマウスを乗せると
<span class="tooltip-trigger-js" data-tooltip="これはJavaScriptで表示されるツールチップです!">最初のトリガー</span>
が表示されます。もう一つ、
<span class="tooltip-trigger-js" data-tooltip="こっちは別の内容だよ!マウスについてくる感じ!">二番目のトリガー</span>
もあります。
</p>
<p>
クリックで表示する例:
<span class="tooltip-trigger-js-click" data-tooltip="クリックありがとう!もう一度クリックで消えるよ。">ここをクリック!</span>
</p>
<div id="js-tooltip"></div>
: これがツールチップの内容を表示する専用の箱。id
を付けてJavaScriptから簡単にアクセスできるようにする。
.tooltip-trigger-js
: このクラスが付いた要素がツールチップのトリガーになる。
data-tooltip="..."
: この「データ属性」に、ツールチップとして表示したい文字列を書いておく。JavaScriptはここから内容を取り出すんだ。
2. CSSの準備
#js-tooltip
の基本的なスタイルと、トリガー要素の簡単なスタイルをCSSで定義するよ。#js-tooltip
は普段はdisplay: none;
で見えなくしておき、position: fixed;
で画面上のどこにでも表示できるようにしておくのがポイントだ。
#js-tooltip {
position: fixed;
background-color: #2c3e50;
color: white;
padding: 10px 15px;
border-radius: 5px;
font-size: 0.95em;
z-index: 9999;
display: none;
pointer-events: none;
opacity: 0;
transition: opacity 0.2s ease-in-out;
}
.tooltip-trigger-js {
border-bottom: 1px dashed #27ae60;
cursor: help;
}
3. JavaScriptの魔法!
いよいよJavaScriptのコードだ。ちょっと長くなるけど、何をしているかコメントで説明するね。
document.addEventListener('DOMContentLoaded', () => {
const tooltipElement = document.getElementById('js-tooltip');
const triggers = document.querySelectorAll('.tooltip-trigger-js');
const clickTriggers = document.querySelectorAll('.tooltip-trigger-js-click');
let tooltipTimeout;
triggers.forEach(trigger => {
trigger.addEventListener('mouseover', (event) => {
const tooltipText = event.target.dataset.tooltip;
if (tooltipText) {
tooltipElement.textContent = tooltipText;
tooltipElement.style.display = 'block';
requestAnimationFrame(() => {
tooltipElement.style.opacity = '1';
});
moveTooltip(event);
}
});
trigger.addEventListener('mousemove', (event) => {
moveTooltip(event);
});
trigger.addEventListener('mouseout', () => {
tooltipElement.style.opacity = '0';
setTimeout(() => {
tooltipElement.style.display = 'none';
}, 200);
});
});
clickTriggers.forEach(trigger => {
trigger.addEventListener('click', (event) => {
const tooltipText = event.target.dataset.tooltip;
if (tooltipText) {
if (tooltipElement.style.display === 'block' && tooltipElement.textContent === tooltipText) {
tooltipElement.style.opacity = '0';
setTimeout(() => { tooltipElement.style.display = 'none'; }, 200);
} else {
tooltipElement.textContent = tooltipText;
tooltipElement.style.display = 'block';
requestAnimationFrame(() => { tooltipElement.style.opacity = '1'; });
tooltipElement.style.left = event.clientX + 15 + 'px';
tooltipElement.style.top = event.clientY + 15 + 'px';
}
}
});
});
function moveTooltip(event) {
let x = event.clientX;
let y = event.clientY;
const tooltipRect = tooltipElement.getBoundingClientRect();
const viewportWidth = window.innerWidth;
const viewportHeight = window.innerHeight;
if (x + tooltipRect.width + 15 > viewportWidth) {
x = viewportWidth - tooltipRect.width - 15;
} else {
x += 15;
}
if (y + tooltipRect.height + 15 > viewportHeight) {
y = viewportHeight - tooltipRect.height - 15;
} else {
y += 15;
}
if (x < 0) x = 0;
if (y < 0) y = 0;
tooltipElement.style.left = x + 'px';
tooltipElement.style.top = y + 'px';
}
});
このコードでは、主にこんなことをしているよ。
DOMContentLoaded
: HTMLが全部読み込まれてからJavaScriptを実行するためのおまじない。
document.getElementById('js-tooltip')
: IDを使ってツールチップ本体の要素を取得。
document.querySelectorAll('.tooltip-trigger-js')
: 指定したクラス名を持つ全てのトリガー要素を取得。
forEach
ループ: 各トリガー要素に対して、イベントリスナーを設定。
event.target.dataset.tooltip
: イベントが発生した要素のdata-tooltip
属性の値を取得。
tooltipElement.textContent = ...
: ツールチップ本体にテキストを設定。
tooltipElement.style.display = 'block' / 'none'
: ツールチップの表示/非表示を切り替え。
tooltipElement.style.opacity = '1' / '0'
: フェードイン/アウト効果。
event.clientX
, event.clientY
: マウスカーソルのX座標、Y座標を取得。
moveTooltip
関数: ツールチップの位置を調整。画面からはみ出ないような簡単なチェックも入れているよ。
- クリックで表示するツールチップは、表示状態をトグル(切り替え)するようにしている。
✨ デモで体験!
さあ、実際に上のHTML、CSS、JavaScriptを組み合わせるとどうなるか見てみよう!下のテキストにマウスを乗せたり、クリックしたりしてみてね。
JavaScriptの力で、この部分や
この部分にマウスを乗せてみよう。
ツールチップがフワッと表示されて、マウスに少しついてくるのが分かるかな?
さらに、ここをクリックするタイプのツールチップもあるよ!
(実際の動作は、このページに上記のHTML、CSS、JavaScriptが適用されていれば確認できます。)
💡 もっとできること(応用アイデア)
JavaScriptを使えば、ツールチップはもっと色々なことができるようになるよ。
- 遅延表示: マウスを乗せてから0.5秒後に表示する、など。
setTimeout
を使えば実現できる。
- Ajaxで内容を取得: サーバーから最新の情報を取ってきてツールチップに表示する。例えば、ユーザー名にマウスを乗せたらその人のプロフィール概要を表示するなど。
- キーボード操作対応: Tabキーでフォーカスが当たった時にもツールチップを表示できるようにする(アクセシビリティ向上のために大切!)。
- より高度な位置調整: ツールチップが画面の端で隠れないように、自動的に上下左右の位置を賢く変える。
これらは少し高度なテクニックになるけど、基本が分かればきっと挑戦できるはずだ!
🇬🇧英語の豆知識コーナー
JavaScriptプログラミングでよく出てくる言葉だよ!
-
Event Listener
意味:イベントリスナー(特定のイベントの発生を待ち受け、処理を実行する仕組み)
Original: We added an event listener to the button to detect clicks.
意訳:クリックを検知するために、ボタンにイベントリスナーを追加しました。
-
DOM Manipulation
意味:DOM操作(Document Object Model をプログラムで変更すること)
Original: JavaScript is often used for DOM manipulation to make web pages interactive.
意訳:JavaScriptは、ウェブページをインタラクティブにするためのDOM操作によく使われます。
-
Dynamic Content
意味:動的コンテンツ(状況に応じて内容が変化するコンテンツ)
Original: The news feed displays dynamic content that updates frequently.
意訳:ニュースフィードには、頻繁に更新される動的コンテンツが表示されます。
-
Asynchronous (Ajax)
意味:非同期の(処理の完了を待たずに次の処理に進むこと。AjaxはAsynchronous JavaScript and XMLの略)
Original: Ajax allows web pages to update content asynchronously without reloading the entire page.
意訳:Ajaxを使うと、ウェブページ全体を再読み込みすることなく、非同期にコンテンツを更新できます。
まとめ
今回は、JavaScriptを使ってツールチップを作る方法の基本を見てきたね。
- JavaScriptを使うと、CSSだけでは難しかった高度な制御や動的な内容の表示が可能になる。
- イベントリスナーでマウスの動きを捉え、DOM操作でツールチップの表示や内容をコントロールする。
data-*
属性を使えば、HTML側にツールチップの内容を持たせやすい。
JavaScriptのコードは少し複雑に見えるかもしれないけど、一つ一つの命令を追っていけば、何をしているかきっと理解できるはずだよ。実際にコードを書いて動かしてみるのが一番の近道だ!
ツールチップ一つとっても、色々な作り方や工夫の仕方があるんだね。次のページでは、ツールチップを作る上でとても大切な「アクセシビリティ」について考えてみよう。