9
6

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 3 years have passed since last update.

【JavaScript】「とりあえず」でjavascript:void(0)を使うな!!

Posted at

まず初めに

最近よく、

<a href="javascript:void(0)" onclick="なんちゃらー">リンク</a>

というHTMLのコードを見かけるようになりました。
しかし、void関数の意味を理解せずに適当に使っている人が多く

<a href="javascript:void(0);alert('hogehoge');" onclick="~">リンク</a>

のような、全くもって意味の無い使い方をしている方も見受けられます。
なので、本記事では__void関数の仕組み、利用目的、利用方法などについて解説したいと思います__。

void関数ってなんぞや?

まず、void関数について説明したいと思います。
void関数は、引数に何を渡しても必ずundefinedを返す関数です。
説明は以上です。

、というのも、void関数は非常に単純な関数で、「真のundefined」を取得する事を目的に作られています。

いや真のundefinedってなんだよ

実は、古いJavaScriptエンジンのundefinedにはreadonly属性が付いておらず、自由に上書き可能なのです。

console.debug( undefined ); // undefined
let undefined = 1234;
console.debug( undefined ); // 古いjsエンジンだと、「1234」と表示される

これは困りましたね。。
「定義されていない」という事を表すundefinedを勝手に上書きされてしまったら、定義されていないかどうか判別するのにいちいちtypeof演算子を利用しないといけなくなってしまいます。
そこで登場したのがvoid関数です。
この関数は、undefinedでは無く、本当の意味での「真のundefined」を返してくれます。

でも何のためにaタグでJavaScriptURIを実行する際にvoid関数を使うんだよ

ここを理解していない方が多いみたいです。

javascript: から始まる URI をサポートしたブラウザに於いて、それは、URI 内のコードを評価し、戻り値が undefined でなければ、返された値にページコンテンツを置き換えます。void 演算子は、undefined を返すために使用できます。
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Operators/void

はい、こーいう事です。
つまり、__aタグのリンク先がJavaScriptURIの時、その式がundefined以外を返した場合に、その内容をブラウザ上に表示するという仕様__なのです。
具体的には、

<script>
function hogehoge() {
  // 何かの処理
  return "成功";
}
</script>
<a href="javascript:hogehoge();" onclick="alert('クリックされました!');">
  example
</a>

こんなコードがあった時に、IEなどの一部のブラウザでは「example」をクリックした際、アラートが表示された上でドキュメントが「成功」という2文字だけに置き換わってしまいます。その際、「example」のボタンなども全て削除されて上書きされます。

意味不明な仕様ですよね。
既に、ChromeなどのChromiumベースのブラウザでは廃止されました。
でも、今回は紹介出来ませんが、この仕様が役に立つ場合もあります。

誤用

冒頭でお見せした、このコード

<a href="javascript:void(0);alert('hogehoge');" onclick="~">リンク</a>

の何がダメなのか、お分かりになりましたでしょうか?

このaタグのhref先の式が実行された時に返される値は、最後のalert関数の戻り値の「true」です。

なので、JavaScriptURIに対応しているバージョンのIEでこのコードを実行すると、画面の左上に小さくtrueと表示されてしまいます。

では、どうすれば良いのか、、。
と言われましても、__普通にundefined__を返せば良い話です。

おっと、NGワードを使ってしまいました。
NGワードとは、__「普通に」__です。

というのも、昔のJavaScriptエンジンではundefinedを上書き出来てしまうとお伝えした通り、undefinedが別の値に上書きされてしまっていたら、このコード

<a href="javascript:undefined" onclick="~">リンク</a>

はundefinedでは無く、その「別の値」を返してしまい、画面の左上に小さく何か表示されてしまいます。

なので、void関数は__真のundefined__を返すためにあると考えれば、冒頭のコードは

<a href="javascript:void(alert('hogehoge'));" onclick="~">リンク</a>

このように直す事が出来るはずです。

最後に

正直、JavaScriptURIは今更使用するべきではありません。
というのも、XSSの脆弱性の原因になりやすいからです。
XSS対策で有名な、Content-Security-Policyヘッダーを利用したりすると、もはやJavaScriptURIは評価すらされなくなります。

9
6
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
9
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?