• ベストアンサー

javascriptでフォーム部品の参照番号を直接取得する方法はありますか?

現在、下記のようにして参照番号を取得しています(o=フォーム部品)。 フォームの部品数が多くなると、時間が多くかかってしまいます。 直接参照番号を取得する方法があったらおしえてください。 for (i=0;i<o.form.length;i++) { if (document.forms[i].elements[i] == o){alert(i);break;} }

質問者が選んだベストアンサー

  • ベストアンサー
noname#84373
noname#84373
回答No.7

適当に解析してください。 Enterで次の項目へ Shift+Enterで前の項目へ idがa2のところにclass="calc1"を指定します これは、計算1とでも解釈?して Shift+[下]で、計算します 計算式は、1つ手前と、次の項目を加算した合計を計算します 属性がhiddenで、ちと戸惑ってしまった^^; でもこれなら、個々にイベント貼り付けなくてもOK? <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"> <title>test</title> <body> <form name="obj"> <input type="hidden" id="b1" value="55"> <input type="text" id="a0" value="12"><br> <input type="text" id="a1" value="34"><br> <input type="text" id="a2" value="56" class="calc1"><br> <input type="text" id="a3" value="78"><br> <input type="text" id="a4" value="90"><br> <input type="hidden" id="b0" value="44"> <input type="text" id="a5" value="99"><br> </form> <script type="text/javascript"> //@cc_on document.body./*@if(1)attachEvent('on'+ @else@*/addEventListener(/*@end@*/'keyup', keyCheck, false); function keyCheck (evt) { var n = evt.target || evt.srcElement; var x, y;  if (evt.keyCode == 13) {   if (evt.shiftKey) {    while ((n = getPreviousTag(n)) && n.type == 'hidden');   } else {    while ((n = getNextTag(n)) && n.type == 'hidden');   }   if (n) n.focus();  }  if (evt.keyCode == 40 && evt.shiftKey) {   if (n.className && n.className.match(/\bcalc1\b/)) {    x = getPreviousTag(n, 1).value-0;//1個手前の数値    y = getNextTag(n,1).value-0;//1個次の数値    n.value = x+y;   }  } } function getNextTag (obj, c) {  var t;  if (c == undefined) c = 0;  while (obj = getNextNode(obj)) {   t = obj.tagName;   if (t == 'INPUT' || t == 'SELECT' || t == 'TEXTAREA') if (1>--c) return obj;  }  return null; } function getPreviousTag (obj, c) {  var t;  if (c == undefined) c = 0;  while (obj = getPreviousNode(obj)) {   t = obj.tagName;   if (t == 'INPUT' || t == 'SELECT' || t == 'TEXTAREA') if (1>--c) return obj;  }  return null; } function getNextNode (node) {  var n;  if (n = node.firstChild) return n;  do if (n = node.nextSibling) return n; while (node = node.parentNode);  return null; } function getPreviousNode (node) {  var n;  if (n = node.previousSibling) {   while (n.hasChildNodes()) n = n.lastChild;   return n;  }  return node.parentNode; } </script>

kaesan
質問者

お礼

丁寧な回答、ありがとうございます。 まだざっと見ただけなんですが、ほとんどこのまま利用できそうな感じです。 previousSibling、nextSiblingというのをしらなかったので、参照番号を取得しないとできないと思っていました。 しっかりと内容を把握してから改めてお礼を申し上げたいと思います。

その他の回答 (7)

noname#84373
noname#84373
回答No.8

コードは一部ここから転用です。 http://www.tagindex.com/cgi-lib/q4bbs/patio.cgi?mode=view&no=2081

kaesan
質問者

お礼

報告が遅くなってすみません。 教えていただいたコードで勉強して、求める動作が全てできるようになりました。 今回教えていただいたpreviousSibling、nextSiblingは、この件に限らず様々に利用できそうでありがたいです。というか不勉強が恥ずかしいです。 本当にありがとうございました。

noname#84373
noname#84373
回答No.6

shift+下は、まだだけど <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"> <title>test</title> <body> <form name="obj"> <input type="text" id="a0"><br> <input type="text" id="a1"><br> <input type="text" id="a2"><br> <input type="text" id="a3"><br> <input type="text" id="a4"><br> <input type="text" id="a5"><br> </form> <script type="text/javascript"> //@cc_on document.body./*@if(1)attachEvent('on'+ @else@*/addEventListener(/*@end@*/'keyup', keyCheck, false); function keyCheck (evt) { var n, o = evt.target || evt.srcElement;  if (evt.keyCode == 13) {   if (evt.shiftKey) {    if (n = getPreviousTag(o)) n.focus();   } else {    if (n = getNextTag(o)) n.focus();   }  } } function getNextTag (obj) {  var o = obj, t;  while (o = getNextNode(o)) {   t = o.tagName;   if (t == 'INPUT' || t == 'SELECT' || t == 'TEXTAREA') return o;  }  return null; } function getPreviousTag (obj) {  var o = obj, t;  while (o = getPreviousNode(o)) {   t = o.tagName;   if (t == 'INPUT' || t == 'SELECT' || t == 'TEXTAREA') return o;  }  return null; } function getNextNode (node) { var n; if (n = node.firstChild) return n; do if (n = node.nextSibling) return n; while (node = node.parentNode); return null; } function getPreviousNode (node) { var n; if (n = node.previousSibling) { while (n.hasChildNodes()) n = n.lastChild; return n; } return node.parentNode; } </script>

noname#84373
noname#84373
回答No.5

その程度であれば、参照番号をカウントする必要がないかも? かなり時間ちょうだい。

noname#84373
noname#84373
回答No.4

ところで参照番号を得て、どんなふうに活用するの?

kaesan
質問者

お礼

onkeyupに設定しているのですが、押されたキーの組み合わせによりフォーカスを移動したり、他の関数を呼び出したりしています。 例えばエンターが押されたら次のフォーム部品へ、Shift+Enterで前の部品へ移動。Shift+下で他の関数呼出し等です。 前の部品、5つ後の部品等の取得にidやnameで処理しきれないため、参照番号を使用しています。

noname#84373
noname#84373
回答No.3

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"> <title>dokodemo kanntann?</title> <input type="text" id="a0"><br> <input type="text" id="a1"><br> <input type="text" id="a2"><br> <input type="text" id="a3"><br> <input type="text" id="a4"><br> <input type="text" id="a5"><br> <script type="text/javascript"> //@cc_on document.body./*@if(1)attachEvent('on'+ @else@*/addEventListener(/*@end@*/'keyup', test, false); function test (evt) { var o = evt.target || evt.srcElement; if (evt.keyCode == 13) alert(o.id); } </script>

kaesan
質問者

お礼

回答ありがとうございます。 この例ですと、フォーム部品のIDが返ってくるようですが、取得したかったのは参照番号です。(私の勘違いでしたらすいません) 記述のしかたは非常に参考になりました。 @cc_onや@ifというのを知りませんでした。 ありがとうございます。 もうしばらくだけ締め切らずにおきたいと思います。 よろしくお願いします。

  • fujillin
  • ベストアンサー率61% (1594/2576)
回答No.2

インデックス番号の取得に限定している質問と思いましたが、どうやらそういうわけでもないみたいですね。 どのような、処理を考えているのか不明ですので、以下で対応できるのかどうかもわかりませんが… >各エレメントのname・IDは、できれば変更したくないです。 イベントの設定でthisなどを引数にしておいて、処理ルーチンはthisをもとに処理するようにしておけば、番号を探さなくても良くなるのでは? オブジェクト間に関係がなくて、↑ような対応ではうまくいかない場合は、onload時にスクリプトでイベントの設定をするようにして、その際にインデックス番号を引数にするなどの設定をしておけば、ファンクションが呼び出された時点ですでにインデックス番号が取得できていることになります。 これなら、最初に一回だけ全体をサーチするだけだなので、ほとんど気にならないと思いますが… 以下、ご参考まで。 <html> <script> window.onload = function(){ var el = document.getElementById('fuga0').firstChild; var indx = 0; while (el){ if (el.nodeName=='LI' && el.firstChild.nodeName=='INPUT'){ var str = el.innerHTML; str = str.substring(0,str.length-2) + ' onkeyup="fuga(' + (indx++) + ')">'; el.innerHTML = str; } el = el.nextSibling; } } function fuga(i){document.getElementById('fuga1').innerHTML=i;} function hoge(e) { var el = e.nextSibling; while (el){ if (el.nodeName=='SPAN'){el.innerHTML = e.value.length;break;} el = el.nextSibling; } } </script> <body> ◆「this」をもとに処理 <ul> <li><input type="text" onkeyup="hoge(this)"> 文字数:<span></span></li> <li><input type="text" onkeyup="hoge(this)"> 文字数:<span></span></li> <li><input type="text" onkeyup="hoge(this)"> 文字数:<span></span></li> </ul> <p style="padding-top:40px;"> ◆「onload」で通し番号を設定 <ul id="fuga0"> onKeyup Index No:<span id="fuga1"></span> <li><input type="text"></li> <li><input type="text"></li> <li><input type="text"></li> </ul> </body> </html></body> </html>

kaesan
質問者

お礼

お礼が遅くなってすいません。 onload時にイベントを設定するのはいい手段ですね。 試してみます。 今回はフォーム部品を含むテーブル要素の動的な追加・削除があるので、そのときにも通し番号を設定するようにしてみます。

  • yambejp
  • ベストアンサー率51% (3827/7415)
回答No.1

>フォームの部品数が多くなると、時間が多くかかってしまいます。 これは「実際に時間がかかって困っている」のでしょうか? それとも「理論的にオーバーヘッドが多いので」ダイレクトに アクセスできるプロパティを探しているのでしょうか? いずれにしろそれほど遅くなるとは考えられませんが・・・ イベント時にチェックが入るのがおそいイメージであれば あらかじめ、各エレメントに参照番号を付加してやるというのも 手かもしれません。

kaesan
質問者

補足

「実際に時間がかかって困ってい」ます。 私のPCの力不足もあると思いますが、フォーム部品の数が500?位になると約3秒かかります。(onkeyupイベントに設定して、Enetrが押されるごとに実行していますので、かなりストレスになるんです。) フォームの上の方(参照番号の若い)部品では問題ありませんが、下の方で時間がかかってしまいます。 それで、参照番号を直接取得できればと思ったのですが。 >各エレメントに参照番号を付加してやるというのも どのようなページ(フォーム)でも使用できるよう考えていますので、各エレメントのname・IDは、できれば変更したくないです。

関連するQ&A