はじめに
前回の記事では、addEventListenerを使ったイベント処理の基本と、イベント委任の仕組みについて解説しました。
今回は、そのイベント処理の知識も使いながら、Webページに欠かせないリンク(<a>タグ)をJavaScriptで操作する方法を解説します。hrefの書き換え、クリック時の挙動の制御、外部リンクの判定とtarget="_blank"の自動設定、ページ内リンクのスムーズスクロールまで、実務でよく使う内容を中心に紹介します。
リンク( <a>タグ ) の基本をおさらい
まずはHTMLの<a>タグの基本をおさらいします。
<a href="https://www.kurumico.com/" target="_blank" rel="noopener noreferrer">kurumico.comへ</a>| 属性 | 内容 |
|---|---|
href | リンク先のURL(ページ内リンクの場合は#id) |
target | リンクの開き方(_blankで新しいタブ) |
rel | リンク先との関係性(noopener・noreferrerなど) |
target="_blank"とrel="noopener noreferrer"の組み合わせについては、後述の「外部リンクを判定してtarget=”_blank”を自動設定する」で詳しく扱います。
リンク要素を取得する
前回の記事や【JavaScript】documentオブジェクトを解説で紹介したquerySelectorAllを使うと、ページ内のリンクをまとめて取得できます。
const links = document.querySelectorAll("a");
links.forEach((link) => {
console.log(link.href, link.textContent);
});querySelectorAll("a")は該当するすべての<a>要素をNodeListとして返すため、forEachで1つずつ処理できます。
link.hrefはHTMLに書かれた値そのままではなく、常に完全なURL(絶対パス)に変換されて取得できます。相対パスで書かれたhref=”/about/”も、取得時にはhttps://example.com/about/のような形になります。
hrefを操作する
リンク先を書き換えたい場合は、hrefプロパティに直接代入します。
const link = document.getElementById("myLink");
link.href = "https://www.kurumico.com/";これはあくまでリンクの属性を書き換えるだけで、その場でページ移動が起きるわけではありません。ユーザーがクリックした時点で、書き換え後のURLに移動します。
一方、【JavaScript】ブラウザとwindowオブジェクトを解説で紹介したlocation.hrefに代入すると、その場で即座にページ移動が発生します。両者は似ていますが、「リンクの見た目・遷移先を変えるだけ」か「今すぐ移動する」かという役割の違いがあるので使い分けに注意しましょう。
クリックイベントを制御する(確認してから遷移する)
リンクをクリックした際に、確認なしにそのまま移動してほしくない場面もあります。そうした場合はpreventDefault()でリンクの標準動作(ページ移動)をキャンセルし、条件を満たしたときだけ手動で移動させます。
const link = document.getElementById("logoutLink");
link.addEventListener("click", (event) => {
event.preventDefault(); // 標準のページ移動をキャンセル
const ok = confirm("ログアウトしますか?");
if (ok) {
location.href = link.href; // OKが押されたら手動で移動
}
});【JavaScript】ダイアログボックスを解説で紹介したconfirm()と組み合わせることで、「本当に移動してよいか」をユーザーに確認してから遷移させる、といった制御ができます。
外部リンクを判定してtarget=”_blank”を自動設定する
サイト内に外部サイトへのリンクが多い場合、<a>タグ1つずつにtarget="_blank"を手書きするのは手間がかかります。JavaScriptを使えば、リンク先のホスト名を調べて自動で外部リンクだけに設定できます。
const links = document.querySelectorAll("a");
links.forEach((link) => {
// hostnameが現在のページと異なれば外部リンクと判定
if (link.hostname !== location.hostname) {
link.target = "_blank";
link.rel = "noopener noreferrer";
}
});link.hostnameにはリンク先のドメイン部分だけが入るため、現在のページのlocation.hostname(【JavaScript】ブラウザとwindowオブジェクトを解説で解説)と比較するだけで、外部リンクかどうかを判定できます。
target=”_blank”だけを設定すると、開いた新しいタブから元のページ(window.opener)を操作できてしまうセキュリティ上の問題があります。rel=”noopener noreferrer”を必ずセットで指定し、この参照を断ち切りましょう。
ページ内リンク(アンカーリンク)をスムーズスクロールにする
href="#id"のようなページ内リンクは、通常クリックすると一瞬でその位置にジャンプします。preventDefault()とscrollIntoView()を組み合わせると、なめらかにスクロールさせられます。
<a href="#section2">セクション2へ</a>
...
<h2 id="section2">セクション2</h2>const anchorLinks = document.querySelectorAll('a[href^="#"]');
anchorLinks.forEach((link) => {
link.addEventListener("click", (event) => {
event.preventDefault();
const targetId = link.getAttribute("href").slice(1); // "#"を除去
const target = document.getElementById(targetId);
target.scrollIntoView({ behavior: "smooth" });
});
});querySelectorAll('a[href^="#"]')は「hrefが#で始まる」リンクだけを絞り込むCSSセレクタです。scrollIntoView({ behavior: "smooth" })を使うことで、瞬間移動ではなくなめらかなスクロールになります。
実務サンプル(外部リンクの自動設定+アンカーリンクのスムーズスクロール)
ページ内のすべてのリンクを対象に、外部リンクにはtarget="_blank"、ページ内リンクにはスムーズスクロールをまとめて設定するサンプルです。
HTML
<nav>
<a href="#section1">セクション1</a>
<a href="#section2">セクション2</a>
<a href="https://www.kurumico.com/">外部サイトへ</a>
</nav>
<h2 id="section1">セクション1</h2>
<p>...</p>
<h2 id="section2">セクション2</h2>
<p>...</p>JavaScript(main.js)
document.addEventListener("DOMContentLoaded", () => {
const links = document.querySelectorAll("a");
links.forEach((link) => {
const isAnchor = link.getAttribute("href").startsWith("#");
if (isAnchor) {
// ページ内リンク:スムーズスクロール
link.addEventListener("click", (event) => {
event.preventDefault();
const targetId = link.getAttribute("href").slice(1);
document.getElementById(targetId).scrollIntoView({ behavior: "smooth" });
});
} else if (link.hostname !== location.hostname) {
// 外部リンク:新しいタブで開く
link.target = "_blank";
link.rel = "noopener noreferrer";
}
});
});すべての<a>要素を1回のループで処理し、hrefが#から始まるものはスムーズスクロール、ホスト名が異なるものは外部リンクとしてtargetとrelを設定しています。ページ内リンクと外部リンクの判定を1つの処理にまとめることで、リンクの数が増えても個別に設定する必要がありません。
よくある質問・エラー対処
Q. hrefプロパティとgetAttribute("href")は何が違う?
→ link.hrefはブラウザが解釈した完全なURL(絶対パス)になりますが、link.getAttribute("href")はHTMLに書かれた値をそのまま返します。href="#section1"と書かれていた場合、link.hrefはhttps://example.com/page/#section1のような完全な形になり、#から始まるかどうかの判定には使えません。前述のサンプルでgetAttribute("href")を使っているのはこのためです。
Q. rel="noopener"とrel="noreferrer"の違いがわからない
→ noopenerは新しいタブから元のページ(window.opener)への参照を断ち切るためのものです。noreferrerはこれに加えて、リンク先へ「どのページから来たか(リファラー)」の情報を送らないようにします。セキュリティ目的であれば、基本的に両方セットで指定しておけば問題ありません。
Q. preventDefault()を呼んだのにページ内リンクがジャンプしてしまう
→ addEventListenerの登録漏れや、対象のリンクがquerySelectorAllの条件(a[href^="#"]など)に一致していないことが原因の可能性があります。まずconsole.log(link)でイベントが正しく登録されているか確認してみてください。
おわりに(まとめ)
JavaScriptでリンク(aタグ)を操作すると、外部リンクの安全な新規タブ表示や、ページ内リンクのスムーズスクロールなど、使い勝手を高める工夫ができます。
- ✅ link.hrefでリンク先の書き換え・取得ができる(location.hrefとは役割が異なる)
- ✅ クリック時にpreventDefault()+confirm()で遷移前の確認ができる
- ✅ link.hostnameとlocation.hostnameの比較で外部リンクを判定できる
- ✅ target=”_blank”には必ずrel=”noopener noreferrer”をセットで指定する
- ✅ href^=”#”のページ内リンクはscrollIntoView({behavior: “smooth”})でなめらかに
まずは外部リンクの判定とtarget=”_blank”の自動設定から試してみましょう。
次回は、<img>タグを使ったイメージ(画像)の操作方法について解説予定です。
この記事が、少しでも誰かのお役に立てれば幸いです。
関連記事
- 【JavaScript】イベント処理を解説
- 【JavaScript】documentオブジェクトを解説
- 【JavaScript】ダイアログボックスを解説
- 【JavaScript】ウィンドウの操作方法を解説
- 【JavaScript】ブラウザとwindowオブジェクトを解説
- 【JavaScript】JavaScriptとは?基本を解説
- Webページに関する基礎的な勉強を始めます
当サイトの記事で使用したVBAなどのサンプルをDLできます
この記事のサンプルはありません!
ダウンロードページへは下のカードをクリックすればジャンプできます。
よろしければご利用ください!

