ajax! Enterでフォーカス移動
日本では昔から需要のあるフォーカスのEnterキー移動。
欲しくなったので実装してみました。すんません、ajaxでもなんでもないです・・・
prototype.jsを使ってクロススクリプティングになっています。
IE、Firefox、Operaで動作確認してあります。
どなたか偉い人、まずい部分を指摘、もしくはリファクタリングよろしくお願いします〜。
var TabEmurator = Class.create() TabEmurator.prototype = { initialize: function(hook_event_key, options) { this.event_key = hook_event_key || Event.KEY_RETURN; this.options = { tags: ['input', 'select'], //エミュレート対象とするタグ auto_numbring: true, //タブインデックスの自動設定の有無 }; Object.extend(this.options, options || {}); this.setup(); }, setup: function() { var all_tags = document.getElementsByTagName('*') || document.all; //Get AllTag var elements = new Array(); if (this.options.auto_numbring) { //エミュレート対象タグの取得 elements = $A(all_tags).select*1; }).bind(this)); //オートナンバリング elements.each(function(element, index) { element.tabIndex = index+1; //1がスタート }); } else { //エミュレート対象タグの取得、タブインデックスの昇順でソート elements = $A(all_tags).select 0 && this.options.tags.include(child_tag.tagName.toLowerCase(">*2; }).bind(this)).sortBy(function(element) { return element.tabIndex; }); } this.elements = elements; }, move: function(event) { if(event.keyCode != this.event_key) return; var base_element = Event.element(event); if (base_element.type != 'button') { Event.stop(event); var next = event.shiftKey ? this._prev(base_element) : this._next(base_element); try{ Field.activate(next); /* focus+select */} catch(e) { return; } } }, _prev: function(base_element) { var min_tabIndex = this.elements[0].tabIndex; //タブ値がMAXの場合、次のフォーカスタグは最小タブ値とする。 if (base_element.tabIndex == min_tabIndex) { return this.elements[this.elements.length-1]; } else { for(var i=this.elements.length-1; i>=0; i--) { var next = this.elements[i]; //フォーカス移動 if (next.tabIndex < base_element.tabIndex ) { return next; } } } return; }, _next: function(base_element) { var max_tabIndex = this.elements[this.elements.length-1].tabIndex; //タブ値がMAXの場合、次のフォーカスタグは最小タブ値とする。 if (base_element.tabIndex == max_tabIndex) { return this.elements[0]; } else { for(var i=0, len=this.elements.length; ibase_element.tabIndex ) { return next; } } } return; } }
コードの説明をすると、
オプションの tags: でタブ移動をエミュレートしたい対象のタグを指定して、
auto_numbring: で、タブインデックスの番号付けを自動か手動かを指定できます。
後は、こんな感じにloadイベントで呼び出してください。
*やっぱり、keydownイベントの登録処理は内部に持たせてたほうがいいかな。
var tab_emu = null; window.onload = function() { tab_emu = new TabEmurator(13, {tags:['input']}); $A(tab_emu.elements).each(function(element) { Event.observe(element, 'keydown', tab_emu.move.bind(tabemu), false); });
Tags: web, ajax, javascript
*1:function(child_tag) { return !child_tag.disabled && child_tag.type != "hidden" && this.options.tags.include(child_tag.tagName.toLowerCase(
*2:function(child_tag) { return !child_tag.disabled && child_tag.type != "hidden" && child_tag.tabIndex > 0 && this.options.tags.include(child_tag.tagName.toLowerCase(