小さい頃はエラ呼吸

いつのまにやら肺で呼吸をしています。


onclickとonkeypressは一緒に指定するべきだと習ったけど、必ずしもそうではないという話

はじめに

僕はお仕事でWebページを作るとき、できるだけWeb標準に従うよう書き上げたHTMLを文法チェッカーにかけて、文法上の問題がないかどうかを確認するようにしています。
文法チェッカーを使うと、onclick属性とonkeypress属性は一緒に指定しなさいと指摘されることがあります。僕はこれを正しいことだと思い、できるかぎりonclickとonkeypressを同時に使用するようにしていました。
ですが、最近になってonclickとonkeypressの両方のイベントを指定すると意図しない動作をすることが分かりました。

onclickとonkeypressに同じイベントハンドラを指定する

具体的には、以下のようなコードを書いていました。onclickとonkeypressに同じイベントハンドラを指定しています。このコードはボタンが押されたたら、画面に表示されている値を+1していきます。普通にマウスでクリックしているときは問題ないのですが、Enterキーを押されたときの動作がちょっとおかしくなります。

<html lang="ja">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>onclickとonkeypress</title>
<script type="text/javascript" charset="UTF-8">
  function hoge() {
    var a = document.getElementById("out").innerHTML;
    a = parseInt(a) + 1;
    document.getElementById("out").innerHTML = a;
  }
</script>
</head>
<body>
<h1>onclickとonkeypressのサンプル</h1>
<input type="button" id="btnOpen" value="ボタン" onclick="hoge()" onkeypress="hoge()">
<div id="out">0</div>
</body>
</html>
Enterキーを押すとonclickとonkeypressで2つイベントが発生する

このコードはボタンをEnterキーで押すと、数字が2つずつ増えて行きます。onclickとonkeypressに同じイベントハンドラを指定すると、両方呼び出されてしまうのです。

onclickとonkeypressの違い

もう1つの問題はEnterキーを長押ししたときの動作です。
onclick属性のみを指定していた場合、Enterキーを長押ししてもキーを離すまではイベントが発生しません。一方、onkeypressを指定した場合、押している間は連続してイベントが発生してしまいます。
仮にボタンのクリックでフォームをサブミットさせていた場合、Enterキーの長押しによって不要なリクエストが大量にサーバに送りつけられてしまう可能性があります。

onekeypressは使わないという解

onkeypressは指定しなくても特に問題ありません。むしろ上記のような問題が発生する可能性があるため、onclickとonkeypressは併用しないほうが良いと思います。
以下のサイトでもそのように書かれています。

基本的には、「onclick 属性のしてある要素に onkeypress も指定する」という思想は、現状では妄信に近いものです。
めんどくさければ「onclick を指定してあれば onkeypress は指定しない」のが一番です。onclick が指定されていれば、世の中のWebサイト閲覧者の9割は(例えキーボード操作を強いられようとも)そんなに困らないような作りになっていますから。つまりその方がよっぽど『高ユーザビリティを保てるようになっている』のですから。
【提案】onkeypressの正しい併用の仕方! - 研究室 はてなブックマーク - 【提案】onkeypressの正しい併用の仕方! - 研究室