よくあるWebフォームの表現で、入力欄が空欄の時は「入力してください」のようなデフォルトの文言が出ていて、フォーカスを当てると空欄になるような仕掛けがあります。この表現は、placeholderとか、watermarks(透かし)と呼ばれるようで、HTML5の場合は標準機能のようです。また、jqueryを使用している場合はプラグインもあるようですが、既存のページで対応しなければいけない場合のための、ライブラリなしの実装しました。地味にはまったので、メモを残します。
なお以下の実装を導き出す際、@Otchyさんに助言を参考にさせていただきました。ありがとうございます。
http://twitter.com/otchy/status/37740505953468416
http://twitter.com/otchy/status/37742189345775616
実装手順
例えば備考フォームを作ろうとしたとします。
<html><body> <form name="form1" method="GET" action="http://www.google.com"> <textarea name="biko"></textarea> <input type="submit"> </form> </body></html>
bikoの下にダミーのテキストエリアを配置し、displayをnoneにします。
<textarea name="biko_dummy" style="display: none">ご要望などはこちらに入力してください。</textarea>
これでは初期表示時に、ダミーが表示されません。元のHTMLをいじって、
<textarea name="biko" style="display: none"></textarea> <textarea name="biko_dummy">ご要望などはこちらに入力してください。</textarea>
このようにすれば、問題ないですが、万が一、JavaScriptが動かなかった場合、メインが表示されなくなってしまいます。そこで、この書き方はせず、JavaScriptで以下のようにします。
document.forms.form1.biko.onblur();
ところが、この書き方ではIE8では、「戻る」ボタンがうまく動きませんでした。戻るボタンの時にJavaScriptが走ってしまい、その時点では、まだbikoの値がロードされていないようで、必ずダミーが出現してしまいます。
以下のようにすることで回避できました!
setTimeout(function() {document.forms.form1.biko.onblur()}, 10);
if (window.attachEvent) { window.attachEvent('onload', function() {document.forms.seisanForm.biko.onblur();}); } else { document.forms.seisanForm.biko.onblur(); }
完成コード
<html> <body> <form name="form1" method="GET" action="http://www.google.com"> <textarea name="biko"></textarea> <textarea name="biko_dummy" style="display: none">ご要望などはこちらに入力してください。</textarea> <input type="submit"> </form> <script type="text/javascript"> function onblurForm1Biko() { if (this.value == '') { this.style.display = 'none'; this.form.biko_dummy.style.display = 'inline'; } } function onfocusForm1BikoDummy() { this.form.biko.style.display = 'inline'; this.style.display = 'none'; this.form.biko.focus(); } document.forms.form1.biko.onblur = onblurForm1Biko; document.forms.form1.biko_dummy.onfocus = onfocusForm1BikoDummy; if (window.attachEvent) { window.attachEvent('onload', function() {document.forms.seisanForm.biko.onblur();}); } else { document.forms.seisanForm.biko.onblur(); } </script> </body> </html>
今回の場合、フォーム送信の時に "biko_dummy"の値も送信されてしまう問題があり、それを回避する場合は、textareaではなく、spanかなにかにすれば良いのですが、そうすると、デザイン調整とか、onfocusが使えないなど面倒なところもあるので、今回は上記実装で妥協しました。
以下、動作するサンプルです。
2011/02/18追記
setTimeoutよりもonloadの方が美しいと指摘を頂いたので、修正しました。ただ、既にonloadが使われている場合に厄介なので、attachEventを、(今回はIEだけの問題なので)存在チェック付きで使用しました。
やはり、jQuery使いたいですよね。