code up

スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

Placeholder Polyfill (IE7) - jQuery placeholderプラグインの紹介

テキストボックスに薄い文字をオーバーレイしてフォーカスがあたる、または文字の入力が開始されると消えていく入力支援を行う機能、HTML5ではplaceholderと言うらしいです。あるいは他ではhintと呼ぶこともあるみたい。私が自前で作る時はhintという名前をつけていました。

以下Windows 8 Pro w/ IE10のIE7モード、IE10、IE9、Chrome(25.0.1364.97 m)、あとiOS6.1.2のSafariでテスト。

自前で作ったスクリプトはヒント文字を画像で用意しておいて、背景画像を入れ替えるというもの。ご想像の通りこの場合いちいち画像を用意しなくてはいけないのでとても大変。

よくあるfocus/blurでテキスト文字とテキスト色を入れ替えるのは、次に挙げたようなことを考慮しなくてはならず、かなり実装は大変だと思ってます。完全に攻略したコードは私には書けず、途中で断念し上述の画像の入れ替え方式としていた。

  • クロスブラウザで動作すること(現状はIE9以下をサポートできればよさげ)
  • ヒント文字列と同じ文字列を入力して送信できること
  • submit時、ヒント文字列を送信しないこと
  • submitを中止ボタンで中断した時、ヒント文字列が消えていないこと
  • 文字列を外のアプリケーションからドロップした時、ヒント文字列が消えてドロップした文字で置き換わること(検索で出てくるplaceholder系のjQueryプラグインのほとんどはこのテストが通らない
  • 文字列をドラッグで別のアプリに移動させた時、ヒント文字列が表示されること
  • カット、ペーストでヒント文字列が表示、非表示すること
  • 「戻る」ボタンで戻ってきたとき、適切に動作すること(文字列が残っていればヒント非表示、など)
  • disable, readonly属性を付与しても正しく動作すること
  • Win8+ATOKだとテストできなかったけど、日本語入力中かつ未確定の状態のテキストをフォーカスをあてて持ってきた時に正しく動作すること。MSIMEのテストも必要かも知れない
  • placeholderとは別件の問題のことで、今は不明だがFirefoxでは日本語変換中の文字をリターンキーではなくマウスクリックで確定させたり日本語入力中未確定の状態で別の要素をクリックするとchangeイベントが発生しないという問題があったので、特に日本語入力中のテストも必要かもしれない

ちなみに全体的に次のスタイルを適用しています。

<style type="text/css">
/* jQuery版 */
.hint {
  color: mediumorchid;
}

/* placeholder属性用(WebKit) */
::-webkit-input-placeholder {
	color: mediumorchid;
}
/* placeholder属性用(Firefox 18まで) */
:-moz-placeholder {
	color: mediumorchid;
}
/* placeholder属性用(Firefox 19以上) */
::-moz-placeholder {
	color: mediumorchid;
}
/* placeholder属性用(IE10) */
:-ms-input-placeholder {
	color: mediumorchid;
}

/* jQueryプラグイン版 */
.placeholder {
  color: mediumorchid;
  font-size: 14px !important;
  margin-top: 3px;
}
</style>

SCSS/Compassでスタイルするのであればgithub上にはあるみたいだけど、まだgem update compassでは落ちてこない。ということで自作。

@mixin input-placeholder($color) {
	&:-moz-placeholder {
		color: $color;
	}
	&::-moz-placeholder {
		color: $color;
	}
	&::-webkit-input-placeholder {
		color: $color;
	}
	&:-ms-input-placeholder {
		color: $color;
	}
}

必要に応じて font-sytle とか追加してもいいかも。使い方は、

@include input-placeholder(silver);

jQueryのみで実装

よくあるプラグイン。placeholderをサポートするブラウザでも動作するようtitle属性を利用。上述した通り、IEではテキストをドロップするとヒント文字列は消えずにヒント文字列に挿入される。そのまま送信すると、下記サンプルではヒント文字列込みで送信する。文字色で判定している場合は送信されない、となるでしょう。

<script type="text/javascript">$(function(){
	$('.demo1').each(function(){
		var that = this;
		if($(this).attr('title')){
			$(this).focus(function(){
				console.log('focus');
				if($(this).val()==$(this).attr('title')){
					// 細かく行う場合はここでフォント色を見たり
					$(this).val('').removeClass('hint');
				}
			}).blur(function(){
				console.log('blur');
				if(!$(this).val()){
					$(this).addClass('hint').val($(this).attr('title'));
				}
			}).closest('form').submit(function(){
				if($(that).val() == $(this).attr('title')){
					$(that).val('');
				}
			});

			if(!$(this).val()){
				$(this).addClass('hint').val($(this).attr('title'));
			}
		}
	});
});
</script>

placeholder属性のみ

placeholder属性のみ。当然古いIEだと動作せず。

jQueryプラグイン

HTML5が普及してきた現在、全てのブラウザに対してHTML5を否定してjQueryで組む必要はなく、Polyfill(Webブラウザが標準装備していない機能を提供するダウンロード可能なコード by Wikipedia)だけ提供すればいいのかな、ということでIE7で期待値に近い動作をするjQueryプラグインを探した。

使ってよさげだったのはmccalltd氏のjquery.placeholder。デモがないのは残念。同名のプラグインがあってまぎらわしい・・・。

これは.val()を使ったplaceholderではなく、ヒント文字列をspanにしてオーバーレイする。もちろんネイティブでplaceholderをサポートしている場合は何もしない(ことで後述する軽微な問題もある)。

<script type="text/javascript">$(function(){
  $('.ph').placeholder();
});</script>

いくつか気づいた問題。placeholderをネイティブでサポートする場合、.placeholder()の結果として$.noopを返してくる。つまり、メソッドチェーン(Method chaining)がplaceholder()で終了する可能性がある。例えば $('[placeholder]').placeholder().addClass('foo'); というような呼び出しはplaceholderをサポートするブラウザではエラー($.noopの戻り値が空の関数なのでaddClass()がないと言われる)になる。

もうひとつ、入力した文字を全部選択した上でドラッグで別のフィールドに持って行くとヒント文字列が復帰しない。実用面で考えると、最初にヒント文字列は出ていてユーザーは読んでいるはずなので、実害はないかなーと。

後はabsolutefloatに対応しているとあるが、いずれも左からのみ。右寄せの場合はプラグインを直接直さないと動作しない。

spanでオーバーレイしているので、ヒント文字列を自由に修飾(例えば、ヒント文字だけ小さくしたり)できることやsubmit時に間違えて送信する事の心配も不要。今時であれば古いIEだけテストしておけばいいのでテストも楽かなと思う。

ということで使わせて頂きます m(__)m (MITライセンス)。

公式サイトにはabsoluteやfloatの要素でも動くと書いてあるが未確認です。

関連記事
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。