Posts Tagged ‘JavaScript’

【JavaScript】フォーカス外れた時に消えるカレンダー

WEB上のカレンダーはマウスで枠外をクリックすると消えます。
でもタブキーでフォーカスを移した時は消えません。
googleだかのカレンダーもそうらしいです。
見てないんでよく知りませんが。

 

以前作った船宿ブログの日付入力カレンダーもそうなってたらしいです。
たしかに自分でもタブでどうのという実装をした覚えがないのでそうなのだろうと思います。

 

確認したらクリックでの非表示は実装してあった。
よかった。

 

今日違うシステムのカレンダー機能でその話になり、
船宿の方もタブで(略)がなかったので実装してみることにしました。

 

今回考えた方法はこれ。
(とは言え最初にキーで見ると言ったのは後輩だが)

 

まずカレンダー表示関数の中で

document.onkeydown = calKeyDown;

 

そして以下関数を追加

function calKeyDown(e) {
	var e = (e)? e : ((window.event)? event : null);
	if(9 == e.keyCode) {
		document.onkeyup = calKeyUp;
	}
}

function calKeyUp(e) {
	document.onkeyup = null;
	var e = (e)? e : ((window.event)? event : null);
	//フォーカスされている要素を取る(左IE,Opera、右FireFox)
	var target = (document.activeElement || window.getSelection().focusNode);
	if(!checkParentNode(target, "calendar", 0)) {
		hideCalendar();
	}
}

hideCalendar() はカレンダーを消す関数です。
必ずカレンダーを消す関数の中で document.onkeydown = null; してあげてください。

 

calKeyUp 関数の中で使っている checkParentNode 関数は
枠外クリック判定の時にも使った関数で
オブジェクトの親を遡って特定のクラス名のオブジェクトがあるかを判定します。

//(判定するオブジェクト, 判定に使うクラス名, 遡っている世代数) as boolean
function checkParentNode(pObj, pClass, pNum) {
	if (pNum>9) {
		return false;
	}
	if (pObj.className==pClass) {
		return true;
	}
	if (pObj.parentNode) {
		return checkParentNode(pObj.parentNode, pClass, pNum+1);
	}
	return false;
}

 

キーダウンですぐに消す判定をしないのは、
タブ押した直後はまだフォーカスが移ってないからです。

 

逆にキーアップのイベントだけを見るとどのキーが押されたのかわかりません。
(当然といっちゃ当然)

 

このコードはあまり汎用的とは言えませんね。
特にonkeydownを占有してるところあたり。

 

jQueryだとイベントも追加できるのでそういったもので作るといいかもしれません。